diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6b6d19a2a..f7ea94256 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -67,6 +67,10 @@ jobs: sudo apt-get install linux-modules-extra-$(uname -r) - name: Install nftables run: sudo apt-get install nftables + - name: Install dnsmasq(dhcp server) + run: | + sudo apt-get install dnsmasq + sudo systemctl disable --now dnsmasq - uses: actions/checkout@v4 - name: setup go uses: actions/setup-go@v5 diff --git a/go.mod b/go.mod index d6c7a66f9..e95255888 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,8 @@ require ( github.com/containernetworking/cni v1.2.3 github.com/coreos/go-iptables v0.8.0 github.com/coreos/go-systemd/v22 v22.5.0 - github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c - github.com/d2g/dhcp4client v1.0.0 - github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5 github.com/godbus/dbus/v5 v5.1.0 + github.com/insomniacslk/dhcp v0.0.0-20240829085014-a3a4c1f04475 github.com/mattn/go-shellwords v1.0.12 github.com/networkplumbing/go-nft v0.4.0 github.com/onsi/ginkgo/v2 v2.20.2 @@ -28,17 +26,22 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/containerd/cgroups/v3 v3.0.3 // indirect github.com/containerd/errdefs v0.1.0 // indirect - github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect + github.com/josharian/native v1.1.0 // indirect + github.com/mdlayher/packet v1.1.2 // indirect + github.com/mdlayher/socket v0.5.1 // indirect + github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect github.com/vishvananda/netns v0.0.4 // indirect go.opencensus.io v0.24.0 // indirect golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/tools v0.24.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect diff --git a/go.sum b/go.sum index f90b9c173..799a5d7cb 100644 --- a/go.sum +++ b/go.sum @@ -21,14 +21,6 @@ github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNs github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c h1:Xo2rK1pzOm0jO6abTPIQwbAmqBIOj132otexc1mmzFc= -github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= -github.com/d2g/dhcp4client v1.0.0 h1:suYBsYZIkSlUMEz4TAYCczKf62IA2UWC+O8+KtdOhCo= -github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= -github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5 h1:+CpLbZIeUn94m02LdEKPcgErLJ347NUwxPKs5u8ieiY= -github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= -github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4 h1:itqmmf1PFpC4n5JW+j4BU7X4MTfVurhYRTjODoPb2Y8= -github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -68,10 +60,20 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8= +github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis= +github.com/insomniacslk/dhcp v0.0.0-20240829085014-a3a4c1f04475 h1:hxST5pwMBEOWmxpkX20w9oZG+hXdhKmAIPQ3NGGAxas= +github.com/insomniacslk/dhcp v0.0.0-20240829085014-a3a4c1f04475/go.mod h1:KclMyHxX06VrVr0DJmeFSUb1ankt7xTfoOA35pCkoic= +github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= +github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY= +github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU+x0kew4= +github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= +github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= github.com/networkplumbing/go-nft v0.4.0 h1:kExVMwXW48DOAukkBwyI16h4uhE5lN9iMvQd52lpTyU= github.com/networkplumbing/go-nft v0.4.0/go.mod h1:HnnM+tYvlGAsMU7yoYwXEVLLiDW9gdMmb5HoGcwpuQs= github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= @@ -80,6 +82,8 @@ github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -99,6 +103,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM= +github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA= github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk= github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= @@ -129,6 +135,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/plugins/ipam/dhcp/client.go b/plugins/ipam/dhcp/client.go deleted file mode 100644 index d39ad7fbd..000000000 --- a/plugins/ipam/dhcp/client.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2021 CNI authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "github.com/d2g/dhcp4" - "github.com/d2g/dhcp4client" -) - -const ( - MaxDHCPLen = 576 -) - -// Send the Discovery Packet to the Broadcast Channel -func DhcpSendDiscoverPacket(c *dhcp4client.Client, options dhcp4.Options) (dhcp4.Packet, error) { - discoveryPacket := c.DiscoverPacket() - - for opt, data := range options { - discoveryPacket.AddOption(opt, data) - } - - discoveryPacket.PadToMinSize() - return discoveryPacket, c.SendPacket(discoveryPacket) -} - -// Send Request Based On the offer Received. -func DhcpSendRequest(c *dhcp4client.Client, options dhcp4.Options, offerPacket *dhcp4.Packet) (dhcp4.Packet, error) { - requestPacket := c.RequestPacket(offerPacket) - - for opt, data := range options { - requestPacket.AddOption(opt, data) - } - - requestPacket.PadToMinSize() - - return requestPacket, c.SendPacket(requestPacket) -} - -// Send Decline to the received acknowledgement. -func DhcpSendDecline(c *dhcp4client.Client, acknowledgementPacket *dhcp4.Packet, options dhcp4.Options) (dhcp4.Packet, error) { - declinePacket := c.DeclinePacket(acknowledgementPacket) - - for opt, data := range options { - declinePacket.AddOption(opt, data) - } - - declinePacket.PadToMinSize() - - return declinePacket, c.SendPacket(declinePacket) -} - -// Lets do a Full DHCP Request. -func DhcpRequest(c *dhcp4client.Client, options dhcp4.Options) (bool, dhcp4.Packet, error) { - discoveryPacket, err := DhcpSendDiscoverPacket(c, options) - if err != nil { - return false, discoveryPacket, err - } - - offerPacket, err := c.GetOffer(&discoveryPacket) - if err != nil { - return false, offerPacket, err - } - - requestPacket, err := DhcpSendRequest(c, options, &offerPacket) - if err != nil { - return false, requestPacket, err - } - - acknowledgement, err := c.GetAcknowledgement(&requestPacket) - if err != nil { - return false, acknowledgement, err - } - - acknowledgementOptions := acknowledgement.ParseOptions() - if dhcp4.MessageType(acknowledgementOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.ACK { - return false, acknowledgement, nil - } - - return true, acknowledgement, nil -} - -// Renew a lease backed on the Acknowledgement Packet. -// Returns Successful, The AcknoledgementPacket, Any Errors -func DhcpRenew(c *dhcp4client.Client, acknowledgement dhcp4.Packet, options dhcp4.Options) (bool, dhcp4.Packet, error) { - renewRequest := c.RenewalRequestPacket(&acknowledgement) - - for opt, data := range options { - renewRequest.AddOption(opt, data) - } - - renewRequest.PadToMinSize() - - err := c.SendPacket(renewRequest) - if err != nil { - return false, renewRequest, err - } - - newAcknowledgement, err := c.GetAcknowledgement(&renewRequest) - if err != nil { - return false, newAcknowledgement, err - } - - newAcknowledgementOptions := newAcknowledgement.ParseOptions() - if dhcp4.MessageType(newAcknowledgementOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.ACK { - return false, newAcknowledgement, nil - } - - return true, newAcknowledgement, nil -} - -// Release a lease backed on the Acknowledgement Packet. -// Returns Any Errors -func DhcpRelease(c *dhcp4client.Client, acknowledgement dhcp4.Packet, options dhcp4.Options) error { - release := c.ReleasePacket(&acknowledgement) - - for opt, data := range options { - release.AddOption(opt, data) - } - - release.PadToMinSize() - - return c.SendPacket(release) -} diff --git a/plugins/ipam/dhcp/daemon.go b/plugins/ipam/dhcp/daemon.go index 867ead3fe..2268e1139 100644 --- a/plugins/ipam/dhcp/daemon.go +++ b/plugins/ipam/dhcp/daemon.go @@ -74,7 +74,7 @@ func (d *DHCP) Allocate(args *skel.CmdArgs, result *current.Result) error { return fmt.Errorf("error parsing netconf: %v", err) } - optsRequesting, optsProviding, err := prepareOptions(args.Args, conf.IPAM.ProvideOptions, conf.IPAM.RequestOptions) + opts, err := prepareOptions(args.Args, conf.IPAM.ProvideOptions, conf.IPAM.RequestOptions) if err != nil { return err } @@ -89,7 +89,7 @@ func (d *DHCP) Allocate(args *skel.CmdArgs, result *current.Result) error { } else { hostNetns := d.hostNetnsPrefix + args.Netns l, err = AcquireLease(clientID, hostNetns, args.IfName, - optsRequesting, optsProviding, + opts, d.clientTimeout, d.clientResendMax, d.broadcast) if err != nil { return err diff --git a/plugins/ipam/dhcp/dhcp2_test.go b/plugins/ipam/dhcp/dhcp2_test.go index 9edb4fcd2..5de983714 100644 --- a/plugins/ipam/dhcp/dhcp2_test.go +++ b/plugins/ipam/dhcp/dhcp2_test.go @@ -61,8 +61,7 @@ var _ = Describe("DHCP Multiple Lease Operations", func() { }) // Start the DHCP server - dhcpServerDone, err = dhcpServerStart(originalNS, 2, dhcpServerStopCh) - Expect(err).NotTo(HaveOccurred()) + dhcpServerDone = dhcpServerStart(originalNS, 2, dhcpServerStopCh) // Start the DHCP client daemon dhcpPluginPath, err := exec.LookPath("dhcp") diff --git a/plugins/ipam/dhcp/dhcp_test.go b/plugins/ipam/dhcp/dhcp_test.go index cf5d0c0ee..ba4439f6e 100644 --- a/plugins/ipam/dhcp/dhcp_test.go +++ b/plugins/ipam/dhcp/dhcp_test.go @@ -25,10 +25,6 @@ import ( "sync" "time" - "github.com/d2g/dhcp4" - "github.com/d2g/dhcp4server" - "github.com/d2g/dhcp4server/leasepool" - "github.com/d2g/dhcp4server/leasepool/memorypool" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/vishvananda/netlink" @@ -48,31 +44,43 @@ func getTmpDir() (string, error) { return tmpDir, err } -func dhcpServerStart(netns ns.NetNS, numLeases int, stopCh <-chan bool) (*sync.WaitGroup, error) { - // Add the expected IP to the pool - lp := memorypool.MemoryPool{} +type DhcpServer struct { + cmd *exec.Cmd - Expect(numLeases).To(BeNumerically(">", 0)) - // Currently tests only need at most 2 - Expect(numLeases).To(BeNumerically("<=", 2)) + startAddr net.IP + endAddr net.IP + leaseTime time.Duration +} - // tests expect first lease to be at address 192.168.1.5 - for i := 5; i < numLeases+5; i++ { - err := lp.AddLease(leasepool.Lease{IP: dhcp4.IPAdd(net.IPv4(192, 168, 1, byte(i)), 0)}) - if err != nil { - return nil, fmt.Errorf("error adding IP to DHCP pool: %v", err) - } +func (s *DhcpServer) Serve() error { + s.cmd = exec.Command( + "dnsmasq", + "--no-daemon", + "--dhcp-sequential-ip", // allocate IPs sequentially + "--port=0", // disable DNS + "--conf-file=-", // Do not read /etc/dnsmasq.conf + fmt.Sprintf("--dhcp-range=%s,%s,%d", s.startAddr, s.endAddr, int(s.leaseTime.Seconds())), + ) + s.cmd.Stdin = bytes.NewBufferString("") + s.cmd.Stdout = os.Stdout + s.cmd.Stderr = os.Stderr + + return s.cmd.Start() +} + +func (s *DhcpServer) Stop() error { + if err := s.cmd.Process.Kill(); err != nil { + return err } + _, err := s.cmd.Process.Wait() + return err +} - dhcpServer, err := dhcp4server.New( - net.IPv4(192, 168, 1, 1), - &lp, - dhcp4server.SetLocalAddr(net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 67}), - dhcp4server.SetRemoteAddr(net.UDPAddr{IP: net.IPv4bcast, Port: 68}), - dhcp4server.LeaseDuration(time.Minute*15), - ) - if err != nil { - return nil, fmt.Errorf("failed to create DHCP server: %v", err) +func dhcpServerStart(netns ns.NetNS, numLeases int, stopCh <-chan bool) *sync.WaitGroup { + dhcpServer := &DhcpServer{ + startAddr: net.IPv4(192, 168, 1, 5), + endAddr: net.IPv4(192, 168, 1, 5+uint8(numLeases)-1), + leaseTime: 5 * time.Minute, } stopWg := sync.WaitGroup{} @@ -84,9 +92,10 @@ func dhcpServerStart(netns ns.NetNS, numLeases int, stopCh <-chan bool) (*sync.W go func() { defer GinkgoRecover() - err = netns.Do(func(ns.NetNS) error { + err := netns.Do(func(ns.NetNS) error { startWg.Done() - if err := dhcpServer.ListenAndServe(); err != nil { + + if err := dhcpServer.Serve(); err != nil { // Log, but don't trap errors; the server will // always report an error when stopped GinkgoT().Logf("DHCP server finished with error: %v", err) @@ -103,12 +112,12 @@ func dhcpServerStart(netns ns.NetNS, numLeases int, stopCh <-chan bool) (*sync.W go func() { startWg.Done() <-stopCh - dhcpServer.Shutdown() + dhcpServer.Stop() stopWg.Done() }() startWg.Wait() - return &stopWg, nil + return &stopWg } const ( @@ -200,8 +209,7 @@ var _ = Describe("DHCP Operations", func() { }) // Start the DHCP server - dhcpServerDone, err = dhcpServerStart(originalNS, 1, dhcpServerStopCh) - Expect(err).NotTo(HaveOccurred()) + dhcpServerDone = dhcpServerStart(originalNS, 1, dhcpServerStopCh) // Start the DHCP client daemon dhcpPluginPath, err := exec.LookPath("dhcp") @@ -517,8 +525,7 @@ var _ = Describe("DHCP Lease Unavailable Operations", func() { }) // Start the DHCP server - dhcpServerDone, err = dhcpServerStart(originalNS, 1, dhcpServerStopCh) - Expect(err).NotTo(HaveOccurred()) + dhcpServerDone = dhcpServerStart(originalNS, 1, dhcpServerStopCh) // Start the DHCP client daemon dhcpPluginPath, err := exec.LookPath("dhcp") diff --git a/plugins/ipam/dhcp/lease.go b/plugins/ipam/dhcp/lease.go index 8928c79de..2e68eb0f6 100644 --- a/plugins/ipam/dhcp/lease.go +++ b/plugins/ipam/dhcp/lease.go @@ -15,6 +15,7 @@ package main import ( + "context" "fmt" "log" "math/rand" @@ -24,8 +25,8 @@ import ( "sync/atomic" "time" - "github.com/d2g/dhcp4" - "github.com/d2g/dhcp4client" + dhcp4 "github.com/insomniacslk/dhcp/dhcpv4" + "github.com/insomniacslk/dhcp/dhcpv4/nclient4" "github.com/vishvananda/netlink" "github.com/containernetworking/cni/pkg/types" @@ -35,8 +36,9 @@ import ( // RFC 2131 suggests using exponential backoff, starting with 4sec // and randomized to +/- 1sec const ( - resendDelay0 = 4 * time.Second - resendDelayMax = 62 * time.Second + resendDelay0 = 4 * time.Second + resendDelayMax = 62 * time.Second + defaultLeaseTime = 60 * time.Minute ) // To speed up the retry for first few failures, we retry without @@ -60,8 +62,7 @@ const ( type DHCPLease struct { clientID string - ack *dhcp4.Packet - opts dhcp4.Options + latestLease *nclient4.Lease link netlink.Link renewalTime time.Time rebindingTime time.Time @@ -73,21 +74,22 @@ type DHCPLease struct { stop chan struct{} check chan struct{} wg sync.WaitGroup + cancelFunc context.CancelFunc + ctx context.Context // list of requesting and providing options and if they are necessary / their value - optsRequesting map[dhcp4.OptionCode]bool - optsProviding map[dhcp4.OptionCode][]byte + opts []dhcp4.Option } -var requestOptionsDefault = map[dhcp4.OptionCode]bool{ - dhcp4.OptionRouter: true, - dhcp4.OptionSubnetMask: true, +var requestOptionsDefault = []dhcp4.OptionCode{ + dhcp4.OptionRouter, + dhcp4.OptionSubnetMask, } func prepareOptions(cniArgs string, provideOptions []ProvideOption, requestOptions []RequestOption) ( - map[dhcp4.OptionCode]bool, map[dhcp4.OptionCode][]byte, error, + []dhcp4.Option, error, ) { - var optsRequesting map[dhcp4.OptionCode]bool - var optsProviding map[dhcp4.OptionCode][]byte + var opts []dhcp4.Option + var err error // parse CNI args cniArgsParsed := map[string]string{} @@ -100,46 +102,51 @@ func prepareOptions(cniArgs string, provideOptions []ProvideOption, requestOptio // parse providing options map var optParsed dhcp4.OptionCode - optsProviding = make(map[dhcp4.OptionCode][]byte) for _, opt := range provideOptions { optParsed, err = parseOptionName(string(opt.Option)) if err != nil { - return nil, nil, fmt.Errorf("Can not parse option %q: %w", opt.Option, err) + return nil, fmt.Errorf("Can not parse option %q: %w", opt.Option, err) } if len(opt.Value) > 0 { if len(opt.Value) > 255 { - return nil, nil, fmt.Errorf("value too long for option %q: %q", opt.Option, opt.Value) + return nil, fmt.Errorf("value too long for option %q: %q", opt.Option, opt.Value) } - optsProviding[optParsed] = []byte(opt.Value) + opts = append(opts, dhcp4.Option{Code: optParsed, Value: dhcp4.String(opt.Value)}) } if value, ok := cniArgsParsed[opt.ValueFromCNIArg]; ok { if len(value) > 255 { - return nil, nil, fmt.Errorf("value too long for option %q from CNI_ARGS %q: %q", opt.Option, opt.ValueFromCNIArg, opt.Value) + return nil, fmt.Errorf("value too long for option %q from CNI_ARGS %q: %q", opt.Option, opt.ValueFromCNIArg, opt.Value) } - optsProviding[optParsed] = []byte(value) + opts = append(opts, dhcp4.Option{Code: optParsed, Value: dhcp4.String(value)}) } } // parse necessary options map - optsRequesting = make(map[dhcp4.OptionCode]bool) + var optsRequesting dhcp4.OptionCodeList skipRequireDefault := false for _, opt := range requestOptions { if opt.SkipDefault { skipRequireDefault = true } + if opt.Option == "" { + continue + } optParsed, err = parseOptionName(string(opt.Option)) if err != nil { - return nil, nil, fmt.Errorf("Can not parse option %q: %w", opt.Option, err) + return nil, fmt.Errorf("Can not parse option %q: %w", opt.Option, err) } - optsRequesting[optParsed] = true + optsRequesting.Add(optParsed) } - for k, v := range requestOptionsDefault { - // only set if not skipping default and this value does not exists - if _, ok := optsRequesting[k]; !ok && !skipRequireDefault { - optsRequesting[k] = v + if !skipRequireDefault { + for _, opt := range requestOptionsDefault { + optsRequesting.Add(opt) } } - return optsRequesting, optsProviding, err + if len(optsRequesting) > 0 { + opts = append(opts, dhcp4.Option{Code: dhcp4.OptionParameterRequestList, Value: optsRequesting}) + } + + return opts, err } // AcquireLease gets an DHCP lease and then maintains it in the background @@ -147,19 +154,24 @@ func prepareOptions(cniArgs string, provideOptions []ProvideOption, requestOptio // calling DHCPLease.Stop() func AcquireLease( clientID, netns, ifName string, - optsRequesting map[dhcp4.OptionCode]bool, optsProviding map[dhcp4.OptionCode][]byte, + opts []dhcp4.Option, timeout, resendMax time.Duration, broadcast bool, ) (*DHCPLease, error) { errCh := make(chan error, 1) + + ctx := context.Background() + ctx, cancel := context.WithCancel(ctx) + l := &DHCPLease{ - clientID: clientID, - stop: make(chan struct{}), - check: make(chan struct{}), - timeout: timeout, - resendMax: resendMax, - broadcast: broadcast, - optsRequesting: optsRequesting, - optsProviding: optsProviding, + clientID: clientID, + stop: make(chan struct{}), + check: make(chan struct{}), + timeout: timeout, + resendMax: resendMax, + broadcast: broadcast, + opts: opts, + cancelFunc: cancel, + ctx: ctx, } log.Printf("%v: acquiring lease", clientID) @@ -209,28 +221,20 @@ func (l *DHCPLease) Check() { l.check <- struct{}{} } -func (l *DHCPLease) getOptionsWithClientID() dhcp4.Options { - opts := make(dhcp4.Options) - opts[dhcp4.OptionClientIdentifier] = []byte(l.clientID) - // client identifier's first byte is "type" - newClientID := []byte{0} - newClientID = append(newClientID, opts[dhcp4.OptionClientIdentifier]...) - opts[dhcp4.OptionClientIdentifier] = newClientID - return opts -} - -func (l *DHCPLease) getAllOptions() dhcp4.Options { - opts := l.getOptionsWithClientID() - - for k, v := range l.optsProviding { - opts[k] = v +func withClientID(clientID string) dhcp4.Modifier { + return func(d *dhcp4.DHCPv4) { + optClientID := []byte{0} + optClientID = append(optClientID, []byte(clientID)...) + d.Options.Update(dhcp4.OptClientIdentifier(optClientID)) } +} - opts[dhcp4.OptionParameterRequestList] = []byte{} - for k := range l.optsRequesting { - opts[dhcp4.OptionParameterRequestList] = append(opts[dhcp4.OptionParameterRequestList], byte(k)) +func withAllOptions(l *DHCPLease) dhcp4.Modifier { + return func(d *dhcp4.DHCPv4) { + for _, opt := range l.opts { + d.Options.Update(opt) + } } - return opts } func (l *DHCPLease) acquire() error { @@ -241,60 +245,39 @@ func (l *DHCPLease) acquire() error { } } - c, err := newDHCPClient(l.link, l.timeout, l.broadcast) + c, err := newDHCPClient(l.link, l.timeout) if err != nil { return err } defer c.Close() - opts := l.getAllOptions() - - pkt, err := backoffRetry(l.resendMax, func() (*dhcp4.Packet, error) { - ok, ack, err := DhcpRequest(c, opts) - switch { - case err != nil: - return nil, err - case !ok: - return nil, fmt.Errorf("DHCP server NACK'd own offer") - default: - return &ack, nil - } + pkt, err := backoffRetry(l.resendMax, func() (*nclient4.Lease, error) { + return c.Request( + l.ctx, + withClientID(l.clientID), + withAllOptions(l), + ) }) if err != nil { return err } - return l.commit(pkt) + l.commit(pkt) + return nil } -func (l *DHCPLease) commit(ack *dhcp4.Packet) error { - opts := ack.ParseOptions() - - leaseTime, err := parseLeaseTime(opts) - if err != nil { - return err - } - - rebindingTime, err := parseRebindingTime(opts) - if err != nil || rebindingTime > leaseTime { - // Per RFC 2131 Section 4.4.5, it should default to 85% of lease time - rebindingTime = leaseTime * 85 / 100 - } +func (l *DHCPLease) commit(lease *nclient4.Lease) { + l.latestLease = lease + ack := lease.ACK - renewalTime, err := parseRenewalTime(opts) - if err != nil || renewalTime > rebindingTime { - // Per RFC 2131 Section 4.4.5, it should default to 50% of lease time - renewalTime = leaseTime / 2 - } + leaseTime := ack.IPAddressLeaseTime(defaultLeaseTime) + rebindingTime := ack.IPAddressRebindingTime(leaseTime * 85 / 100) + renewalTime := ack.IPAddressRenewalTime(leaseTime / 2) now := time.Now() l.expireTime = now.Add(leaseTime) l.renewalTime = now.Add(renewalTime) l.rebindingTime = now.Add(rebindingTime) - l.ack = ack - l.opts = opts - - return nil } func (l *DHCPLease) maintain() { @@ -362,44 +345,38 @@ func (l *DHCPLease) downIface() { } func (l *DHCPLease) renew() error { - c, err := newDHCPClient(l.link, l.timeout, l.broadcast) + c, err := newDHCPClient(l.link, l.timeout) if err != nil { return err } defer c.Close() - opts := l.getAllOptions() - pkt, err := backoffRetry(l.resendMax, func() (*dhcp4.Packet, error) { - ok, ack, err := DhcpRenew(c, *l.ack, opts) - switch { - case err != nil: - return nil, err - case !ok: - return nil, fmt.Errorf("DHCP server did not renew lease") - default: - return &ack, nil - } + lease, err := backoffRetry(l.resendMax, func() (*nclient4.Lease, error) { + return c.Renew( + l.ctx, + l.latestLease, + withClientID(l.clientID), + withAllOptions(l), + ) }) if err != nil { return err } - l.commit(pkt) + l.commit(lease) return nil } func (l *DHCPLease) release() error { log.Printf("%v: releasing lease", l.clientID) - c, err := newDHCPClient(l.link, l.timeout, l.broadcast) + c, err := newDHCPClient(l.link, l.timeout) if err != nil { return err } defer c.Close() - opts := l.getOptionsWithClientID() - - if err = DhcpRelease(c, *l.ack, opts); err != nil { + if err = c.Release(l.latestLease, withClientID(l.clientID)); err != nil { return fmt.Errorf("failed to send DHCPRELEASE") } @@ -407,33 +384,47 @@ func (l *DHCPLease) release() error { } func (l *DHCPLease) IPNet() (*net.IPNet, error) { - mask := parseSubnetMask(l.opts) + ack := l.latestLease.ACK + + mask := ack.SubnetMask() if mask == nil { return nil, fmt.Errorf("DHCP option Subnet Mask not found in DHCPACK") } return &net.IPNet{ - IP: l.ack.YIAddr(), + IP: ack.YourIPAddr, Mask: mask, }, nil } func (l *DHCPLease) Gateway() net.IP { - return parseRouter(l.opts) + ack := l.latestLease.ACK + gws := ack.Router() + if len(gws) > 0 { + return gws[0] + } + return nil } func (l *DHCPLease) Routes() []*types.Route { routes := []*types.Route{} + ack := l.latestLease.ACK + // RFC 3442 states that if Classless Static Routes (option 121) // exist, we ignore Static Routes (option 33) and the Router/Gateway. - opt121Routes := parseCIDRRoutes(l.opts) + opt121Routes := ack.ClasslessStaticRoute() if len(opt121Routes) > 0 { - return append(routes, opt121Routes...) + for _, r := range opt121Routes { + routes = append(routes, &types.Route{Dst: *r.Dest, GW: r.Router}) + } + return routes } // Append Static Routes - routes = append(routes, parseRoutes(l.opts)...) + if ack.Options.Has(dhcp4.OptionStaticRoutingTable) { + routes = append(routes, parseRoutes(ack.Options.Get(dhcp4.OptionStaticRoutingTable))...) + } // The CNI spec says even if there is a gateway specified, we must // add a default route in the routes section. @@ -450,7 +441,7 @@ func jitter(span time.Duration) time.Duration { return time.Duration(float64(span) * (2.0*rand.Float64() - 1.0)) } -func backoffRetry(resendMax time.Duration, f func() (*dhcp4.Packet, error)) (*dhcp4.Packet, error) { +func backoffRetry(resendMax time.Duration, f func() (*nclient4.Lease, error)) (*nclient4.Lease, error) { baseDelay := resendDelay0 var sleepTime time.Duration fastRetryLimit := resendFastMax @@ -487,17 +478,8 @@ func backoffRetry(resendMax time.Duration, f func() (*dhcp4.Packet, error)) (*dh func newDHCPClient( link netlink.Link, timeout time.Duration, - broadcast bool, -) (*dhcp4client.Client, error) { - pktsock, err := dhcp4client.NewPacketSock(link.Attrs().Index) - if err != nil { - return nil, err - } - - return dhcp4client.New( - dhcp4client.HardwareAddr(link.Attrs().HardwareAddr), - dhcp4client.Timeout(timeout), - dhcp4client.Broadcast(broadcast), - dhcp4client.Connection(pktsock), - ) + clientOpts ...nclient4.ClientOpt, +) (*nclient4.Client, error) { + clientOpts = append(clientOpts, nclient4.WithTimeout(timeout)) + return nclient4.New(link.Attrs().Name, clientOpts...) } diff --git a/plugins/ipam/dhcp/options.go b/plugins/ipam/dhcp/options.go index f9fd472db..deb152a2d 100644 --- a/plugins/ipam/dhcp/options.go +++ b/plugins/ipam/dhcp/options.go @@ -15,13 +15,11 @@ package main import ( - "encoding/binary" "fmt" "net" "strconv" - "time" - "github.com/d2g/dhcp4" + dhcp4 "github.com/insomniacslk/dhcp/dhcpv4" "github.com/containernetworking/cni/pkg/types" ) @@ -31,8 +29,8 @@ var optionNameToID = map[string]dhcp4.OptionCode{ "subnet-mask": dhcp4.OptionSubnetMask, "routers": dhcp4.OptionRouter, "host-name": dhcp4.OptionHostName, - "user-class": dhcp4.OptionUserClass, - "vendor-class-identifier": dhcp4.OptionVendorClassIdentifier, + "user-class": dhcp4.OptionUserClassInformation, + "vendor-class-identifier": dhcp4.OptionClassIdentifier, } func parseOptionName(option string) (dhcp4.OptionCode, error) { @@ -41,18 +39,9 @@ func parseOptionName(option string) (dhcp4.OptionCode, error) { } i, err := strconv.ParseUint(option, 10, 8) if err != nil { - return 0, fmt.Errorf("Can not parse option: %w", err) + return dhcp4.OptionPad, fmt.Errorf("Can not parse option: %w", err) } - return dhcp4.OptionCode(i), nil -} - -func parseRouter(opts dhcp4.Options) net.IP { - if opts, ok := opts[dhcp4.OptionRouter]; ok { - if len(opts) == 4 { - return net.IP(opts) - } - } - return nil + return dhcp4.GenericOptionCode(i), nil } func classfulSubnet(sn net.IP) net.IPNet { @@ -62,100 +51,22 @@ func classfulSubnet(sn net.IP) net.IPNet { } } -func parseRoutes(opts dhcp4.Options) []*types.Route { +func parseRoutes(opt []byte) []*types.Route { // StaticRoutes format: pairs of: // Dest = 4 bytes; Classful IP subnet // Router = 4 bytes; IP address of router routes := []*types.Route{} - if opt, ok := opts[dhcp4.OptionStaticRoute]; ok { - for len(opt) >= 8 { - sn := opt[0:4] - r := opt[4:8] - rt := &types.Route{ - Dst: classfulSubnet(sn), - GW: r, - } - routes = append(routes, rt) - opt = opt[8:] + for len(opt) >= 8 { + sn := opt[0:4] + r := opt[4:8] + rt := &types.Route{ + Dst: classfulSubnet(sn), + GW: r, } + routes = append(routes, rt) + opt = opt[8:] } return routes } - -func parseCIDRRoutes(opts dhcp4.Options) []*types.Route { - // See RFC4332 for format (http://tools.ietf.org/html/rfc3442) - - routes := []*types.Route{} - if opt, ok := opts[dhcp4.OptionClasslessRouteFormat]; ok { - for len(opt) >= 5 { - width := int(opt[0]) - if width > 32 { - // error: can't have more than /32 - return nil - } - // network bits are compacted to avoid zeros - octets := 0 - if width > 0 { - octets = (width-1)/8 + 1 - } - - if len(opt) < 1+octets+4 { - // error: too short - return nil - } - - sn := make([]byte, 4) - copy(sn, opt[1:octets+1]) - - gw := net.IP(opt[octets+1 : octets+5]) - - rt := &types.Route{ - Dst: net.IPNet{ - IP: net.IP(sn), - Mask: net.CIDRMask(width, 32), - }, - GW: gw, - } - routes = append(routes, rt) - - opt = opt[octets+5:] - } - } - return routes -} - -func parseSubnetMask(opts dhcp4.Options) net.IPMask { - mask, ok := opts[dhcp4.OptionSubnetMask] - if !ok { - return nil - } - - return net.IPMask(mask) -} - -func parseDuration(opts dhcp4.Options, code dhcp4.OptionCode, optName string) (time.Duration, error) { - val, ok := opts[code] - if !ok { - return 0, fmt.Errorf("option %v not found", optName) - } - if len(val) != 4 { - return 0, fmt.Errorf("option %v is not 4 bytes", optName) - } - - secs := binary.BigEndian.Uint32(val) - return time.Duration(secs) * time.Second, nil -} - -func parseLeaseTime(opts dhcp4.Options) (time.Duration, error) { - return parseDuration(opts, dhcp4.OptionIPAddressLeaseTime, "LeaseTime") -} - -func parseRenewalTime(opts dhcp4.Options) (time.Duration, error) { - return parseDuration(opts, dhcp4.OptionRenewalTimeValue, "RenewalTime") -} - -func parseRebindingTime(opts dhcp4.Options) (time.Duration, error) { - return parseDuration(opts, dhcp4.OptionRebindingTimeValue, "RebindingTime") -} diff --git a/plugins/ipam/dhcp/options_test.go b/plugins/ipam/dhcp/options_test.go index d5ba4cb13..338174a5e 100644 --- a/plugins/ipam/dhcp/options_test.go +++ b/plugins/ipam/dhcp/options_test.go @@ -19,7 +19,7 @@ import ( "reflect" "testing" - "github.com/d2g/dhcp4" + dhcp4 "github.com/insomniacslk/dhcp/dhcpv4" "github.com/containernetworking/cni/pkg/types" ) @@ -61,17 +61,8 @@ func validateRoutes(t *testing.T, routes []*types.Route) { } func TestParseRoutes(t *testing.T) { - opts := make(dhcp4.Options) - opts[dhcp4.OptionStaticRoute] = []byte{10, 0, 0, 0, 10, 1, 2, 3, 192, 168, 1, 0, 192, 168, 2, 3} - routes := parseRoutes(opts) - - validateRoutes(t, routes) -} - -func TestParseCIDRRoutes(t *testing.T) { - opts := make(dhcp4.Options) - opts[dhcp4.OptionClasslessRouteFormat] = []byte{8, 10, 10, 1, 2, 3, 24, 192, 168, 1, 192, 168, 2, 3} - routes := parseCIDRRoutes(opts) + data := []byte{10, 0, 0, 0, 10, 1, 2, 3, 192, 168, 1, 0, 192, 168, 2, 3} + routes := parseRoutes(data) validateRoutes(t, routes) } @@ -87,10 +78,10 @@ func TestParseOptionName(t *testing.T) { "hostname", "host-name", dhcp4.OptionHostName, false, }, { - "hostname in number", "12", dhcp4.OptionHostName, false, + "hostname in number", "12", dhcp4.GenericOptionCode(12), false, }, { - "random string", "doNotparseMe", 0, true, + "random string", "doNotparseMe", dhcp4.OptionPad, true, }, } for _, tt := range tests { diff --git a/vendor/github.com/d2g/dhcp4/README.md b/vendor/github.com/d2g/dhcp4/README.md deleted file mode 100644 index 6752dc71a..000000000 --- a/vendor/github.com/d2g/dhcp4/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# DHCP4 - A DHCP library written in Go. - -Warning: This library is still being developed. Function calls will change. - -I've removed Server Functionality, for me this project supports the underlying DHCP format not the implementation. diff --git a/vendor/github.com/d2g/dhcp4/constants.go b/vendor/github.com/d2g/dhcp4/constants.go deleted file mode 100644 index 183a77837..000000000 --- a/vendor/github.com/d2g/dhcp4/constants.go +++ /dev/null @@ -1,121 +0,0 @@ -package dhcp4 - -// OpCodes -const ( - BootRequest OpCode = 1 // From Client - BootReply OpCode = 2 // From Server -) - -// DHCP Message Type 53 -const ( - Discover MessageType = 1 // Broadcast Packet From Client - Can I have an IP? - Offer MessageType = 2 // Broadcast From Server - Here's an IP - Request MessageType = 3 // Broadcast From Client - I'll take that IP (Also start for renewals) - Decline MessageType = 4 // Broadcast From Client - Sorry I can't use that IP - ACK MessageType = 5 // From Server, Yes you can have that IP - NAK MessageType = 6 // From Server, No you cannot have that IP - Release MessageType = 7 // From Client, I don't need that IP anymore - Inform MessageType = 8 // From Client, I have this IP and there's nothing you can do about it -) - -// DHCP Options -const ( - End OptionCode = 255 - Pad OptionCode = 0 - OptionSubnetMask OptionCode = 1 - OptionTimeOffset OptionCode = 2 - OptionRouter OptionCode = 3 - OptionTimeServer OptionCode = 4 - OptionNameServer OptionCode = 5 - OptionDomainNameServer OptionCode = 6 - OptionLogServer OptionCode = 7 - OptionCookieServer OptionCode = 8 - OptionLPRServer OptionCode = 9 - OptionImpressServer OptionCode = 10 - OptionResourceLocationServer OptionCode = 11 - OptionHostName OptionCode = 12 - OptionBootFileSize OptionCode = 13 - OptionMeritDumpFile OptionCode = 14 - OptionDomainName OptionCode = 15 - OptionSwapServer OptionCode = 16 - OptionRootPath OptionCode = 17 - OptionExtensionsPath OptionCode = 18 - - // IP Layer Parameters per Host - OptionIPForwardingEnableDisable OptionCode = 19 - OptionNonLocalSourceRoutingEnableDisable OptionCode = 20 - OptionPolicyFilter OptionCode = 21 - OptionMaximumDatagramReassemblySize OptionCode = 22 - OptionDefaultIPTimeToLive OptionCode = 23 - OptionPathMTUAgingTimeout OptionCode = 24 - OptionPathMTUPlateauTable OptionCode = 25 - - // IP Layer Parameters per Interface - OptionInterfaceMTU OptionCode = 26 - OptionAllSubnetsAreLocal OptionCode = 27 - OptionBroadcastAddress OptionCode = 28 - OptionPerformMaskDiscovery OptionCode = 29 - OptionMaskSupplier OptionCode = 30 - OptionPerformRouterDiscovery OptionCode = 31 - OptionRouterSolicitationAddress OptionCode = 32 - OptionStaticRoute OptionCode = 33 - - // Link Layer Parameters per Interface - OptionTrailerEncapsulation OptionCode = 34 - OptionARPCacheTimeout OptionCode = 35 - OptionEthernetEncapsulation OptionCode = 36 - - // TCP Parameters - OptionTCPDefaultTTL OptionCode = 37 - OptionTCPKeepaliveInterval OptionCode = 38 - OptionTCPKeepaliveGarbage OptionCode = 39 - - // Application and Service Parameters - OptionNetworkInformationServiceDomain OptionCode = 40 - OptionNetworkInformationServers OptionCode = 41 - OptionNetworkTimeProtocolServers OptionCode = 42 - OptionVendorSpecificInformation OptionCode = 43 - OptionNetBIOSOverTCPIPNameServer OptionCode = 44 - OptionNetBIOSOverTCPIPDatagramDistributionServer OptionCode = 45 - OptionNetBIOSOverTCPIPNodeType OptionCode = 46 - OptionNetBIOSOverTCPIPScope OptionCode = 47 - OptionXWindowSystemFontServer OptionCode = 48 - OptionXWindowSystemDisplayManager OptionCode = 49 - OptionNetworkInformationServicePlusDomain OptionCode = 64 - OptionNetworkInformationServicePlusServers OptionCode = 65 - OptionMobileIPHomeAgent OptionCode = 68 - OptionSimpleMailTransportProtocol OptionCode = 69 - OptionPostOfficeProtocolServer OptionCode = 70 - OptionNetworkNewsTransportProtocol OptionCode = 71 - OptionDefaultWorldWideWebServer OptionCode = 72 - OptionDefaultFingerServer OptionCode = 73 - OptionDefaultInternetRelayChatServer OptionCode = 74 - OptionStreetTalkServer OptionCode = 75 - OptionStreetTalkDirectoryAssistance OptionCode = 76 - - // DHCP Extensions - OptionRequestedIPAddress OptionCode = 50 - OptionIPAddressLeaseTime OptionCode = 51 - OptionOverload OptionCode = 52 - OptionDHCPMessageType OptionCode = 53 - OptionServerIdentifier OptionCode = 54 - OptionParameterRequestList OptionCode = 55 - OptionMessage OptionCode = 56 - OptionMaximumDHCPMessageSize OptionCode = 57 - OptionRenewalTimeValue OptionCode = 58 - OptionRebindingTimeValue OptionCode = 59 - OptionVendorClassIdentifier OptionCode = 60 - OptionClientIdentifier OptionCode = 61 - - OptionTFTPServerName OptionCode = 66 - OptionBootFileName OptionCode = 67 - - OptionUserClass OptionCode = 77 - - OptionClientArchitecture OptionCode = 93 - - OptionTZPOSIXString OptionCode = 100 - OptionTZDatabaseString OptionCode = 101 - - OptionClasslessRouteFormat OptionCode = 121 -) diff --git a/vendor/github.com/d2g/dhcp4/helpers.go b/vendor/github.com/d2g/dhcp4/helpers.go deleted file mode 100644 index 4b1463869..000000000 --- a/vendor/github.com/d2g/dhcp4/helpers.go +++ /dev/null @@ -1,58 +0,0 @@ -package dhcp4 - -import ( - "encoding/binary" - "net" - "time" -) - -// IPRange returns how many ips in the ip range from start to stop (inclusive) -func IPRange(start, stop net.IP) int { - //return int(Uint([]byte(stop))-Uint([]byte(start))) + 1 - return int(binary.BigEndian.Uint32(stop.To4())) - int(binary.BigEndian.Uint32(start.To4())) + 1 -} - -// IPAdd returns a copy of start + add. -// IPAdd(net.IP{192,168,1,1},30) returns net.IP{192.168.1.31} -func IPAdd(start net.IP, add int) net.IP { // IPv4 only - start = start.To4() - //v := Uvarint([]byte(start)) - result := make(net.IP, 4) - binary.BigEndian.PutUint32(result, binary.BigEndian.Uint32(start)+uint32(add)) - //PutUint([]byte(result), v+uint64(add)) - return result -} - -// IPLess returns where IP a is less than IP b. -func IPLess(a, b net.IP) bool { - b = b.To4() - for i, ai := range a.To4() { - if ai != b[i] { - return ai < b[i] - } - } - return false -} - -// IPInRange returns true if ip is between (inclusive) start and stop. -func IPInRange(start, stop, ip net.IP) bool { - return !(IPLess(ip, start) || IPLess(stop, ip)) -} - -// OptionsLeaseTime - converts a time.Duration to a 4 byte slice, compatible -// with OptionIPAddressLeaseTime. -func OptionsLeaseTime(d time.Duration) []byte { - leaseBytes := make([]byte, 4) - binary.BigEndian.PutUint32(leaseBytes, uint32(d/time.Second)) - //PutUvarint(leaseBytes, uint64(d/time.Second)) - return leaseBytes -} - -// JoinIPs returns a byte slice of IP addresses, one immediately after the other -// This may be useful for creating multiple IP options such as OptionRouter. -func JoinIPs(ips []net.IP) (b []byte) { - for _, v := range ips { - b = append(b, v.To4()...) - } - return -} diff --git a/vendor/github.com/d2g/dhcp4/option.go b/vendor/github.com/d2g/dhcp4/option.go deleted file mode 100644 index fbf86e65c..000000000 --- a/vendor/github.com/d2g/dhcp4/option.go +++ /dev/null @@ -1,40 +0,0 @@ -package dhcp4 - -type OptionCode byte - -type Option struct { - Code OptionCode - Value []byte -} - -// Map of DHCP options -type Options map[OptionCode][]byte - -// SelectOrderOrAll has same functionality as SelectOrder, except if the order -// param is nil, whereby all options are added (in arbitrary order). -func (o Options) SelectOrderOrAll(order []byte) []Option { - if order == nil { - opts := make([]Option, 0, len(o)) - for i, v := range o { - opts = append(opts, Option{Code: i, Value: v}) - } - return opts - } - return o.SelectOrder(order) -} - -// SelectOrder returns a slice of options ordered and selected by a byte array -// usually defined by OptionParameterRequestList. This result is expected to be -// used in ReplyPacket()'s []Option parameter. -func (o Options) SelectOrder(order []byte) []Option { - opts := make([]Option, 0, len(order)) - for _, v := range order { - if data, ok := o[OptionCode(v)]; ok { - opts = append(opts, Option{Code: OptionCode(v), Value: data}) - } - } - return opts -} - -type OpCode byte -type MessageType byte // Option 53 diff --git a/vendor/github.com/d2g/dhcp4/packet.go b/vendor/github.com/d2g/dhcp4/packet.go deleted file mode 100644 index 25d69fb99..000000000 --- a/vendor/github.com/d2g/dhcp4/packet.go +++ /dev/null @@ -1,150 +0,0 @@ -package dhcp4 - -import ( - "net" - "time" -) - -// A DHCP packet -type Packet []byte - -func (p Packet) OpCode() OpCode { return OpCode(p[0]) } -func (p Packet) HType() byte { return p[1] } -func (p Packet) HLen() byte { return p[2] } -func (p Packet) Hops() byte { return p[3] } -func (p Packet) XId() []byte { return p[4:8] } -func (p Packet) Secs() []byte { return p[8:10] } // Never Used? -func (p Packet) Flags() []byte { return p[10:12] } -func (p Packet) CIAddr() net.IP { return net.IP(p[12:16]) } -func (p Packet) YIAddr() net.IP { return net.IP(p[16:20]) } -func (p Packet) SIAddr() net.IP { return net.IP(p[20:24]) } -func (p Packet) GIAddr() net.IP { return net.IP(p[24:28]) } -func (p Packet) CHAddr() net.HardwareAddr { - hLen := p.HLen() - if hLen > 16 { // Prevent chaddr exceeding p boundary - hLen = 16 - } - return net.HardwareAddr(p[28 : 28+hLen]) // max endPos 44 -} - -// 192 bytes of zeros BOOTP legacy -func (p Packet) Cookie() []byte { return p[236:240] } -func (p Packet) Options() []byte { - if len(p) > 240 { - return p[240:] - } - return nil -} - -func (p Packet) Broadcast() bool { return p.Flags()[0] > 127 } - -func (p Packet) SetBroadcast(broadcast bool) { - if p.Broadcast() != broadcast { - p.Flags()[0] ^= 128 - } -} - -func (p Packet) SetOpCode(c OpCode) { p[0] = byte(c) } -func (p Packet) SetCHAddr(a net.HardwareAddr) { - copy(p[28:44], a) - p[2] = byte(len(a)) -} -func (p Packet) SetHType(hType byte) { p[1] = hType } -func (p Packet) SetCookie(cookie []byte) { copy(p.Cookie(), cookie) } -func (p Packet) SetHops(hops byte) { p[3] = hops } -func (p Packet) SetXId(xId []byte) { copy(p.XId(), xId) } -func (p Packet) SetSecs(secs []byte) { copy(p.Secs(), secs) } -func (p Packet) SetFlags(flags []byte) { copy(p.Flags(), flags) } -func (p Packet) SetCIAddr(ip net.IP) { copy(p.CIAddr(), ip.To4()) } -func (p Packet) SetYIAddr(ip net.IP) { copy(p.YIAddr(), ip.To4()) } -func (p Packet) SetSIAddr(ip net.IP) { copy(p.SIAddr(), ip.To4()) } -func (p Packet) SetGIAddr(ip net.IP) { copy(p.GIAddr(), ip.To4()) } - -// Parses the packet's options into an Options map -func (p Packet) ParseOptions() Options { - opts := p.Options() - options := make(Options, 10) - for len(opts) >= 2 && OptionCode(opts[0]) != End { - if OptionCode(opts[0]) == Pad { - opts = opts[1:] - continue - } - size := int(opts[1]) - if len(opts) < 2+size { - break - } - options[OptionCode(opts[0])] = opts[2 : 2+size] - opts = opts[2+size:] - } - return options -} - -func NewPacket(opCode OpCode) Packet { - p := make(Packet, 241) - p.SetOpCode(opCode) - p.SetHType(1) // Ethernet - p.SetCookie([]byte{99, 130, 83, 99}) - p[240] = byte(End) - return p -} - -// Appends a DHCP option to the end of a packet -func (p *Packet) AddOption(o OptionCode, value []byte) { - *p = append((*p)[:len(*p)-1], []byte{byte(o), byte(len(value))}...) // Strip off End, Add OptionCode and Length - *p = append(*p, value...) // Add Option Value - *p = append(*p, byte(End)) // Add on new End -} - -// Removes all options from packet. -func (p *Packet) StripOptions() { - *p = append((*p)[:240], byte(End)) -} - -// Creates a request packet that a Client would send to a server. -func RequestPacket(mt MessageType, chAddr net.HardwareAddr, cIAddr net.IP, xId []byte, broadcast bool, options []Option) Packet { - p := NewPacket(BootRequest) - p.SetCHAddr(chAddr) - p.SetXId(xId) - if cIAddr != nil { - p.SetCIAddr(cIAddr) - } - p.SetBroadcast(broadcast) - p.AddOption(OptionDHCPMessageType, []byte{byte(mt)}) - for _, o := range options { - p.AddOption(o.Code, o.Value) - } - p.PadToMinSize() - return p -} - -// ReplyPacket creates a reply packet that a Server would send to a client. -// It uses the req Packet param to copy across common/necessary fields to -// associate the reply the request. -func ReplyPacket(req Packet, mt MessageType, serverId, yIAddr net.IP, leaseDuration time.Duration, options []Option) Packet { - p := NewPacket(BootReply) - p.SetXId(req.XId()) - p.SetFlags(req.Flags()) - p.SetYIAddr(yIAddr) - p.SetGIAddr(req.GIAddr()) - p.SetCHAddr(req.CHAddr()) - p.AddOption(OptionDHCPMessageType, []byte{byte(mt)}) - p.AddOption(OptionServerIdentifier, []byte(serverId)) - if leaseDuration > 0 { - p.AddOption(OptionIPAddressLeaseTime, OptionsLeaseTime(leaseDuration)) - } - for _, o := range options { - p.AddOption(o.Code, o.Value) - } - p.PadToMinSize() - return p -} - -// PadToMinSize pads a packet so that when sent over UDP, the entire packet, -// is 300 bytes (BOOTP min), to be compatible with really old devices. -var padder [272]byte - -func (p *Packet) PadToMinSize() { - if n := len(*p); n < 272 { - *p = append(*p, padder[:272-n]...) - } -} diff --git a/vendor/github.com/d2g/dhcp4client/LICENSE b/vendor/github.com/d2g/dhcp4client/LICENSE deleted file mode 100644 index c33dcc7c9..000000000 --- a/vendor/github.com/d2g/dhcp4client/LICENSE +++ /dev/null @@ -1,354 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. “Contributor” - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. “Contributor Version” - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor’s Contribution. - -1.3. “Contribution” - - means Covered Software of a particular Contributor. - -1.4. “Covered Software” - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. “Incompatible With Secondary Licenses” - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of version - 1.1 or earlier of the License, but not also under the terms of a - Secondary License. - -1.6. “Executable Form” - - means any form of the work other than Source Code Form. - -1.7. “Larger Work” - - means a work that combines Covered Software with other material, in a separate - file or files, that is not Covered Software. - -1.8. “License” - - means this document. - -1.9. “Licensable” - - means having the right to grant, to the maximum extent possible, whether at the - time of the initial grant or subsequently, any and all of the rights conveyed by - this License. - -1.10. “Modifications” - - means any of the following: - - a. any file in Source Code Form that results from an addition to, deletion - from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. “Patent Claims” of a Contributor - - means any patent claim(s), including without limitation, method, process, - and apparatus claims, in any patent Licensable by such Contributor that - would be infringed, but for the grant of the License, by the making, - using, selling, offering for sale, having made, import, or transfer of - either its Contributions or its Contributor Version. - -1.12. “Secondary License” - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. “Source Code Form” - - means the form of the work preferred for making modifications. - -1.14. “You” (or “Your”) - - means an individual or a legal entity exercising rights under this - License. For legal entities, “You” includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, “control” means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or as - part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its Contributions - or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution become - effective for each Contribution on the date the Contributor first distributes - such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under this - License. No additional rights or licenses will be implied from the distribution - or licensing of Covered Software under this License. Notwithstanding Section - 2.1(b) above, no patent license is granted by a Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party’s - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of its - Contributions. - - This License does not grant any rights in the trademarks, service marks, or - logos of any Contributor (except as may be necessary to comply with the - notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this License - (see Section 10.2) or under the terms of a Secondary License (if permitted - under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its Contributions - are its original creation(s) or it has sufficient rights to grant the - rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under applicable - copyright doctrines of fair use, fair dealing, or other equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under the - terms of this License. You must inform recipients that the Source Code Form - of the Covered Software is governed by the terms of this License, and how - they can obtain a copy of this License. You may not attempt to alter or - restrict the recipients’ rights in the Source Code Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this License, - or sublicense it under different terms, provided that the license for - the Executable Form does not attempt to limit or alter the recipients’ - rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for the - Covered Software. If the Larger Work is a combination of Covered Software - with a work governed by one or more Secondary Licenses, and the Covered - Software is not Incompatible With Secondary Licenses, this License permits - You to additionally distribute such Covered Software under the terms of - such Secondary License(s), so that the recipient of the Larger Work may, at - their option, further distribute the Covered Software under the terms of - either this License or such Secondary License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices (including - copyright notices, patent notices, disclaimers of warranty, or limitations - of liability) contained within the Source Code Form of the Covered - Software, except that You may alter any license notices to the extent - required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on behalf - of any Contributor. You must make it absolutely clear that any such - warranty, support, indemnity, or liability obligation is offered by You - alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, judicial - order, or regulation then You must: (a) comply with the terms of this License - to the maximum extent possible; and (b) describe the limitations and the code - they affect. Such description must be placed in a text file included with all - distributions of the Covered Software under this License. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing basis, - if such Contributor fails to notify You of the non-compliance by some - reasonable means prior to 60 days after You have come back into compliance. - Moreover, Your grants from a particular Contributor are reinstated on an - ongoing basis if such Contributor notifies You of the non-compliance by - some reasonable means, this is the first time You have received notice of - non-compliance with this License from such Contributor, and You become - compliant prior to 30 days after Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, counter-claims, - and cross-claims) alleging that a Contributor Version directly or - indirectly infringes any patent, then the rights granted to You by any and - all Contributors for the Covered Software under Section 2.1 of this License - shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an “as is” basis, without - warranty of any kind, either expressed, implied, or statutory, including, - without limitation, warranties that the Covered Software is free of defects, - merchantable, fit for a particular purpose or non-infringing. The entire - risk as to the quality and performance of the Covered Software is with You. - Should any Covered Software prove defective in any respect, You (not any - Contributor) assume the cost of any necessary servicing, repair, or - correction. This disclaimer of warranty constitutes an essential part of this - License. No use of any Covered Software is authorized under this License - except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from such - party’s negligence to the extent applicable law prohibits such limitation. - Some jurisdictions do not allow the exclusion or limitation of incidental or - consequential damages, so this exclusion and limitation may not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts of - a jurisdiction where the defendant maintains its principal place of business - and such litigation shall be governed by laws of that jurisdiction, without - reference to its conflict-of-law provisions. Nothing in this Section shall - prevent a party’s ability to bring cross-claims or counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject matter - hereof. If any provision of this License is held to be unenforceable, such - provision shall be reformed only to the extent necessary to make it - enforceable. Any law or regulation which provides that the language of a - contract shall be construed against the drafter shall not be used to construe - this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version of - the License under which You originally received the Covered Software, or - under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a modified - version of this License if you rename the license and remove any - references to the name of the license steward (except to note that such - modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses - If You choose to distribute Source Code Form that is Incompatible With - Secondary Licenses under the terms of this version of the License, the - notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, then -You may include the notice in a location (such as a LICENSE file in a relevant -directory) where a recipient would be likely to look for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - “Incompatible With Secondary Licenses” Notice - - This Source Code Form is “Incompatible - With Secondary Licenses”, as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/d2g/dhcp4client/README.md b/vendor/github.com/d2g/dhcp4client/README.md deleted file mode 100644 index 785ac2c1d..000000000 --- a/vendor/github.com/d2g/dhcp4client/README.md +++ /dev/null @@ -1,8 +0,0 @@ -dhcp4client [![GoDoc](https://godoc.org/github.com/d2g/dhcp4client?status.svg)](http://godoc.org/github.com/d2g/dhcp4client) [![Coverage Status](https://coveralls.io/repos/d2g/dhcp4client/badge.svg?branch=HEAD)](https://coveralls.io/r/d2g/dhcp4client?branch=HEAD) [![Codeship Status for d2g/dhcp4client](https://codeship.com/projects/d75d9860-b364-0132-bc79-7e1d8cf367b9/status?branch=master)](https://codeship.com/projects/70187) -=========== - -DHCP Client - - -###### Thanks to: -@eyakubovich For AF_PACKET support. diff --git a/vendor/github.com/d2g/dhcp4client/client.go b/vendor/github.com/d2g/dhcp4client/client.go deleted file mode 100644 index 1d43e3076..000000000 --- a/vendor/github.com/d2g/dhcp4client/client.go +++ /dev/null @@ -1,416 +0,0 @@ -package dhcp4client - -import ( - "bytes" - "fmt" - "hash/fnv" - "math/rand" - "net" - "sync" - "syscall" - "time" - - "github.com/d2g/dhcp4" -) - -const ( - MaxDHCPLen = 576 -) - -type Client struct { - hardwareAddr net.HardwareAddr //The HardwareAddr to send in the request. - ignoreServers []net.IP //List of Servers to Ignore requests from. - timeout time.Duration //Time before we timeout. - broadcast bool //Set the Bcast flag in BOOTP Flags - connection ConnectionInt //The Connection Method to use - generateXID func([]byte) //Function Used to Generate a XID -} - -//Abstracts the type of underlying socket used -type ConnectionInt interface { - Close() error - Write(packet []byte) error - ReadFrom() ([]byte, net.IP, error) - SetReadTimeout(t time.Duration) error -} - -func New(options ...func(*Client) error) (*Client, error) { - c := Client{ - timeout: time.Second * 10, - broadcast: true, - } - - err := c.SetOption(options...) - if err != nil { - return nil, err - } - - if c.generateXID == nil { - // https://tools.ietf.org/html/rfc2131#section-4.1 explains: - // - // A DHCP client MUST choose 'xid's in such a way as to minimize the chance - // of using an 'xid' identical to one used by another client. - // - // Hence, seed a random number generator with the current time and hardware - // address. - h := fnv.New64() - h.Write(c.hardwareAddr) - seed := int64(h.Sum64()) + time.Now().Unix() - rnd := rand.New(rand.NewSource(seed)) - var rndMu sync.Mutex - c.generateXID = func(b []byte) { - rndMu.Lock() - defer rndMu.Unlock() - rnd.Read(b) - } - } - - //if connection hasn't been set as an option create the default. - if c.connection == nil { - conn, err := NewInetSock() - if err != nil { - return nil, err - } - c.connection = conn - } - - return &c, nil -} - -func (c *Client) SetOption(options ...func(*Client) error) error { - for _, opt := range options { - if err := opt(c); err != nil { - return err - } - } - return nil -} - -func Timeout(t time.Duration) func(*Client) error { - return func(c *Client) error { - c.timeout = t - return nil - } -} - -func IgnoreServers(s []net.IP) func(*Client) error { - return func(c *Client) error { - c.ignoreServers = s - return nil - } -} - -func HardwareAddr(h net.HardwareAddr) func(*Client) error { - return func(c *Client) error { - c.hardwareAddr = h - return nil - } -} - -func Broadcast(b bool) func(*Client) error { - return func(c *Client) error { - c.broadcast = b - return nil - } -} - -func Connection(conn ConnectionInt) func(*Client) error { - return func(c *Client) error { - c.connection = conn - return nil - } -} - -func GenerateXID(g func([]byte)) func(*Client) error { - return func(c *Client) error { - c.generateXID = g - return nil - } -} - -//Close Connections -func (c *Client) Close() error { - if c.connection != nil { - return c.connection.Close() - } - return nil -} - -//Send the Discovery Packet to the Broadcast Channel -func (c *Client) SendDiscoverPacket() (dhcp4.Packet, error) { - discoveryPacket := c.DiscoverPacket() - discoveryPacket.PadToMinSize() - - return discoveryPacket, c.SendPacket(discoveryPacket) -} - -// TimeoutError records a timeout when waiting for a DHCP packet. -type TimeoutError struct { - Timeout time.Duration -} - -func (te *TimeoutError) Error() string { - return fmt.Sprintf("no DHCP packet received within %v", te.Timeout) -} - -//Retreive Offer... -//Wait for the offer for a specific Discovery Packet. -func (c *Client) GetOffer(discoverPacket *dhcp4.Packet) (dhcp4.Packet, error) { - start := time.Now() - - for { - timeout := c.timeout - time.Since(start) - if timeout < 0 { - return dhcp4.Packet{}, &TimeoutError{Timeout: c.timeout} - } - - c.connection.SetReadTimeout(timeout) - readBuffer, source, err := c.connection.ReadFrom() - if err != nil { - if errno, ok := err.(syscall.Errno); ok && errno == syscall.EAGAIN { - return dhcp4.Packet{}, &TimeoutError{Timeout: c.timeout} - } - return dhcp4.Packet{}, err - } - - offerPacket := dhcp4.Packet(readBuffer) - offerPacketOptions := offerPacket.ParseOptions() - - // Ignore Servers in my Ignore list - for _, ignoreServer := range c.ignoreServers { - if source.Equal(ignoreServer) { - continue - } - - if offerPacket.SIAddr().Equal(ignoreServer) { - continue - } - } - - if len(offerPacketOptions[dhcp4.OptionDHCPMessageType]) < 1 || dhcp4.MessageType(offerPacketOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.Offer || !bytes.Equal(discoverPacket.XId(), offerPacket.XId()) { - continue - } - - return offerPacket, nil - } - -} - -//Send Request Based On the offer Received. -func (c *Client) SendRequest(offerPacket *dhcp4.Packet) (dhcp4.Packet, error) { - requestPacket := c.RequestPacket(offerPacket) - requestPacket.PadToMinSize() - - return requestPacket, c.SendPacket(requestPacket) -} - -//Retreive Acknowledgement -//Wait for the offer for a specific Request Packet. -func (c *Client) GetAcknowledgement(requestPacket *dhcp4.Packet) (dhcp4.Packet, error) { - start := time.Now() - - for { - timeout := c.timeout - time.Since(start) - if timeout < 0 { - return dhcp4.Packet{}, &TimeoutError{Timeout: c.timeout} - } - - c.connection.SetReadTimeout(timeout) - readBuffer, source, err := c.connection.ReadFrom() - if err != nil { - if errno, ok := err.(syscall.Errno); ok && errno == syscall.EAGAIN { - return dhcp4.Packet{}, &TimeoutError{Timeout: c.timeout} - } - return dhcp4.Packet{}, err - } - - acknowledgementPacket := dhcp4.Packet(readBuffer) - acknowledgementPacketOptions := acknowledgementPacket.ParseOptions() - - // Ignore Servers in my Ignore list - for _, ignoreServer := range c.ignoreServers { - if source.Equal(ignoreServer) { - continue - } - - if acknowledgementPacket.SIAddr().Equal(ignoreServer) { - continue - } - } - - if !bytes.Equal(requestPacket.XId(), acknowledgementPacket.XId()) || len(acknowledgementPacketOptions[dhcp4.OptionDHCPMessageType]) < 1 || (dhcp4.MessageType(acknowledgementPacketOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.ACK && dhcp4.MessageType(acknowledgementPacketOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.NAK) { - continue - } - - return acknowledgementPacket, nil - } -} - -//Send Decline to the received acknowledgement. -func (c *Client) SendDecline(acknowledgementPacket *dhcp4.Packet) (dhcp4.Packet, error) { - declinePacket := c.DeclinePacket(acknowledgementPacket) - declinePacket.PadToMinSize() - - return declinePacket, c.SendPacket(declinePacket) -} - -//Send a DHCP Packet. -func (c *Client) SendPacket(packet dhcp4.Packet) error { - return c.connection.Write(packet) -} - -//Create Discover Packet -func (c *Client) DiscoverPacket() dhcp4.Packet { - messageid := make([]byte, 4) - c.generateXID(messageid) - - packet := dhcp4.NewPacket(dhcp4.BootRequest) - packet.SetCHAddr(c.hardwareAddr) - packet.SetXId(messageid) - packet.SetBroadcast(c.broadcast) - - packet.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(dhcp4.Discover)}) - //packet.PadToMinSize() - return packet -} - -//Create Request Packet -func (c *Client) RequestPacket(offerPacket *dhcp4.Packet) dhcp4.Packet { - offerOptions := offerPacket.ParseOptions() - - packet := dhcp4.NewPacket(dhcp4.BootRequest) - packet.SetCHAddr(c.hardwareAddr) - - packet.SetXId(offerPacket.XId()) - packet.SetCIAddr(offerPacket.CIAddr()) - packet.SetSIAddr(offerPacket.SIAddr()) - - packet.SetBroadcast(c.broadcast) - packet.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(dhcp4.Request)}) - packet.AddOption(dhcp4.OptionRequestedIPAddress, (offerPacket.YIAddr()).To4()) - packet.AddOption(dhcp4.OptionServerIdentifier, offerOptions[dhcp4.OptionServerIdentifier]) - - return packet -} - -//Create Request Packet For a Renew -func (c *Client) RenewalRequestPacket(acknowledgement *dhcp4.Packet) dhcp4.Packet { - messageid := make([]byte, 4) - c.generateXID(messageid) - - acknowledgementOptions := acknowledgement.ParseOptions() - - packet := dhcp4.NewPacket(dhcp4.BootRequest) - packet.SetCHAddr(acknowledgement.CHAddr()) - - packet.SetXId(messageid) - packet.SetCIAddr(acknowledgement.YIAddr()) - packet.SetSIAddr(acknowledgement.SIAddr()) - - packet.SetBroadcast(c.broadcast) - packet.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(dhcp4.Request)}) - packet.AddOption(dhcp4.OptionRequestedIPAddress, (acknowledgement.YIAddr()).To4()) - packet.AddOption(dhcp4.OptionServerIdentifier, acknowledgementOptions[dhcp4.OptionServerIdentifier]) - - return packet -} - -//Create Release Packet For a Release -func (c *Client) ReleasePacket(acknowledgement *dhcp4.Packet) dhcp4.Packet { - messageid := make([]byte, 4) - c.generateXID(messageid) - - acknowledgementOptions := acknowledgement.ParseOptions() - - packet := dhcp4.NewPacket(dhcp4.BootRequest) - packet.SetCHAddr(acknowledgement.CHAddr()) - - packet.SetXId(messageid) - packet.SetCIAddr(acknowledgement.YIAddr()) - - packet.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(dhcp4.Release)}) - packet.AddOption(dhcp4.OptionServerIdentifier, acknowledgementOptions[dhcp4.OptionServerIdentifier]) - - return packet -} - -//Create Decline Packet -func (c *Client) DeclinePacket(acknowledgement *dhcp4.Packet) dhcp4.Packet { - messageid := make([]byte, 4) - c.generateXID(messageid) - - acknowledgementOptions := acknowledgement.ParseOptions() - - packet := dhcp4.NewPacket(dhcp4.BootRequest) - packet.SetCHAddr(acknowledgement.CHAddr()) - packet.SetXId(messageid) - - packet.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(dhcp4.Decline)}) - packet.AddOption(dhcp4.OptionRequestedIPAddress, (acknowledgement.YIAddr()).To4()) - packet.AddOption(dhcp4.OptionServerIdentifier, acknowledgementOptions[dhcp4.OptionServerIdentifier]) - - return packet -} - -//Lets do a Full DHCP Request. -func (c *Client) Request() (bool, dhcp4.Packet, error) { - discoveryPacket, err := c.SendDiscoverPacket() - if err != nil { - return false, discoveryPacket, err - } - - offerPacket, err := c.GetOffer(&discoveryPacket) - if err != nil { - return false, offerPacket, err - } - - requestPacket, err := c.SendRequest(&offerPacket) - if err != nil { - return false, requestPacket, err - } - - acknowledgement, err := c.GetAcknowledgement(&requestPacket) - if err != nil { - return false, acknowledgement, err - } - - acknowledgementOptions := acknowledgement.ParseOptions() - if dhcp4.MessageType(acknowledgementOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.ACK { - return false, acknowledgement, nil - } - - return true, acknowledgement, nil -} - -//Renew a lease backed on the Acknowledgement Packet. -//Returns Sucessfull, The AcknoledgementPacket, Any Errors -func (c *Client) Renew(acknowledgement dhcp4.Packet) (bool, dhcp4.Packet, error) { - renewRequest := c.RenewalRequestPacket(&acknowledgement) - renewRequest.PadToMinSize() - - err := c.SendPacket(renewRequest) - if err != nil { - return false, renewRequest, err - } - - newAcknowledgement, err := c.GetAcknowledgement(&renewRequest) - if err != nil { - return false, newAcknowledgement, err - } - - newAcknowledgementOptions := newAcknowledgement.ParseOptions() - if dhcp4.MessageType(newAcknowledgementOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.ACK { - return false, newAcknowledgement, nil - } - - return true, newAcknowledgement, nil -} - -//Release a lease backed on the Acknowledgement Packet. -//Returns Any Errors -func (c *Client) Release(acknowledgement dhcp4.Packet) error { - release := c.ReleasePacket(&acknowledgement) - release.PadToMinSize() - - return c.SendPacket(release) -} diff --git a/vendor/github.com/d2g/dhcp4client/generatexid.go b/vendor/github.com/d2g/dhcp4client/generatexid.go deleted file mode 100644 index 6e9ffbcde..000000000 --- a/vendor/github.com/d2g/dhcp4client/generatexid.go +++ /dev/null @@ -1,18 +0,0 @@ -package dhcp4client - -import ( - cryptorand "crypto/rand" - mathrand "math/rand" -) - -func CryptoGenerateXID(b []byte) { - if _, err := cryptorand.Read(b); err != nil { - panic(err) - } -} - -func MathGenerateXID(b []byte) { - if _, err := mathrand.Read(b); err != nil { - panic(err) - } -} diff --git a/vendor/github.com/d2g/dhcp4client/inetsock.go b/vendor/github.com/d2g/dhcp4client/inetsock.go deleted file mode 100644 index 293f18653..000000000 --- a/vendor/github.com/d2g/dhcp4client/inetsock.go +++ /dev/null @@ -1,75 +0,0 @@ -package dhcp4client - -import ( - "net" - "time" -) - -type inetSock struct { - *net.UDPConn - - laddr net.UDPAddr - raddr net.UDPAddr -} - -func NewInetSock(options ...func(*inetSock) error) (*inetSock, error) { - c := &inetSock{ - laddr: net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 68}, - raddr: net.UDPAddr{IP: net.IPv4bcast, Port: 67}, - } - - err := c.setOption(options...) - if err != nil { - return nil, err - } - - conn, err := net.ListenUDP("udp4", &c.laddr) - if err != nil { - return nil, err - } - - c.UDPConn = conn - return c, err -} - -func (c *inetSock) setOption(options ...func(*inetSock) error) error { - for _, opt := range options { - if err := opt(c); err != nil { - return err - } - } - return nil -} - -func SetLocalAddr(l net.UDPAddr) func(*inetSock) error { - return func(c *inetSock) error { - c.laddr = l - return nil - } -} - -func SetRemoteAddr(r net.UDPAddr) func(*inetSock) error { - return func(c *inetSock) error { - c.raddr = r - return nil - } -} - -func (c *inetSock) Write(packet []byte) error { - _, err := c.WriteToUDP(packet, &c.raddr) - return err -} - -func (c *inetSock) ReadFrom() ([]byte, net.IP, error) { - readBuffer := make([]byte, MaxDHCPLen) - n, source, err := c.ReadFromUDP(readBuffer) - if source != nil { - return readBuffer[:n], source.IP, err - } else { - return readBuffer[:n], net.IP{}, err - } -} - -func (c *inetSock) SetReadTimeout(t time.Duration) error { - return c.SetReadDeadline(time.Now().Add(t)) -} diff --git a/vendor/github.com/d2g/dhcp4client/pktsock_linux.go b/vendor/github.com/d2g/dhcp4client/pktsock_linux.go deleted file mode 100644 index 99b53521c..000000000 --- a/vendor/github.com/d2g/dhcp4client/pktsock_linux.go +++ /dev/null @@ -1,147 +0,0 @@ -package dhcp4client - -import ( - "encoding/binary" - "math/rand" - "net" - "time" - - "golang.org/x/sys/unix" -) - -const ( - minIPHdrLen = 20 - maxIPHdrLen = 60 - udpHdrLen = 8 - ip4Ver = 0x40 - ttl = 16 - srcPort = 68 - dstPort = 67 -) - -var ( - bcastMAC = []byte{255, 255, 255, 255, 255, 255} -) - -// abstracts AF_PACKET -type packetSock struct { - fd int - ifindex int -} - -func NewPacketSock(ifindex int) (*packetSock, error) { - fd, err := unix.Socket(unix.AF_PACKET, unix.SOCK_DGRAM, int(swap16(unix.ETH_P_IP))) - if err != nil { - return nil, err - } - - addr := unix.SockaddrLinklayer{ - Ifindex: ifindex, - Protocol: swap16(unix.ETH_P_IP), - } - - if err = unix.Bind(fd, &addr); err != nil { - return nil, err - } - - return &packetSock{ - fd: fd, - ifindex: ifindex, - }, nil -} - -func (pc *packetSock) Close() error { - return unix.Close(pc.fd) -} - -func (pc *packetSock) Write(packet []byte) error { - lladdr := unix.SockaddrLinklayer{ - Ifindex: pc.ifindex, - Protocol: swap16(unix.ETH_P_IP), - Halen: uint8(len(bcastMAC)), - } - copy(lladdr.Addr[:], bcastMAC) - - pkt := make([]byte, minIPHdrLen+udpHdrLen+len(packet)) - - fillIPHdr(pkt[0:minIPHdrLen], udpHdrLen+uint16(len(packet))) - fillUDPHdr(pkt[minIPHdrLen:minIPHdrLen+udpHdrLen], uint16(len(packet))) - - // payload - copy(pkt[minIPHdrLen+udpHdrLen:len(pkt)], packet) - - return unix.Sendto(pc.fd, pkt, 0, &lladdr) -} - -func (pc *packetSock) ReadFrom() ([]byte, net.IP, error) { - pkt := make([]byte, maxIPHdrLen+udpHdrLen+MaxDHCPLen) - n, _, err := unix.Recvfrom(pc.fd, pkt, 0) - if err != nil { - return nil, nil, err - } - - // IP hdr len - ihl := int(pkt[0]&0x0F) * 4 - // Source IP address - src := net.IP(pkt[12:16]) - - return pkt[ihl+udpHdrLen : n], src, nil -} - -func (pc *packetSock) SetReadTimeout(t time.Duration) error { - - tv := unix.NsecToTimeval(t.Nanoseconds()) - return unix.SetsockoptTimeval(pc.fd, unix.SOL_SOCKET, unix.SO_RCVTIMEO, &tv) -} - -// compute's 1's complement checksum -func chksum(p []byte, csum []byte) { - cklen := len(p) - s := uint32(0) - for i := 0; i < (cklen - 1); i += 2 { - s += uint32(p[i+1])<<8 | uint32(p[i]) - } - if cklen&1 == 1 { - s += uint32(p[cklen-1]) - } - s = (s >> 16) + (s & 0xffff) - s = s + (s >> 16) - s = ^s - - csum[0] = uint8(s & 0xff) - csum[1] = uint8(s >> 8) -} - -func fillIPHdr(hdr []byte, payloadLen uint16) { - // version + IHL - hdr[0] = ip4Ver | (minIPHdrLen / 4) - // total length - binary.BigEndian.PutUint16(hdr[2:4], uint16(len(hdr))+payloadLen) - // identification - if _, err := rand.Read(hdr[4:5]); err != nil { - panic(err) - } - // TTL - hdr[8] = 16 - // Protocol - hdr[9] = unix.IPPROTO_UDP - // dst IP - copy(hdr[16:20], net.IPv4bcast.To4()) - // compute IP hdr checksum - chksum(hdr[0:len(hdr)], hdr[10:12]) -} - -func fillUDPHdr(hdr []byte, payloadLen uint16) { - // src port - binary.BigEndian.PutUint16(hdr[0:2], srcPort) - // dest port - binary.BigEndian.PutUint16(hdr[2:4], dstPort) - // length - binary.BigEndian.PutUint16(hdr[4:6], udpHdrLen+payloadLen) -} - -func swap16(x uint16) uint16 { - var b [2]byte - binary.BigEndian.PutUint16(b[:], x) - return binary.LittleEndian.Uint16(b[:]) -} diff --git a/vendor/github.com/d2g/dhcp4server/LICENSE b/vendor/github.com/d2g/dhcp4server/LICENSE deleted file mode 100644 index c33dcc7c9..000000000 --- a/vendor/github.com/d2g/dhcp4server/LICENSE +++ /dev/null @@ -1,354 +0,0 @@ -Mozilla Public License, version 2.0 - -1. Definitions - -1.1. “Contributor” - - means each individual or legal entity that creates, contributes to the - creation of, or owns Covered Software. - -1.2. “Contributor Version” - - means the combination of the Contributions of others (if any) used by a - Contributor and that particular Contributor’s Contribution. - -1.3. “Contribution” - - means Covered Software of a particular Contributor. - -1.4. “Covered Software” - - means Source Code Form to which the initial Contributor has attached the - notice in Exhibit A, the Executable Form of such Source Code Form, and - Modifications of such Source Code Form, in each case including portions - thereof. - -1.5. “Incompatible With Secondary Licenses” - means - - a. that the initial Contributor has attached the notice described in - Exhibit B to the Covered Software; or - - b. that the Covered Software was made available under the terms of version - 1.1 or earlier of the License, but not also under the terms of a - Secondary License. - -1.6. “Executable Form” - - means any form of the work other than Source Code Form. - -1.7. “Larger Work” - - means a work that combines Covered Software with other material, in a separate - file or files, that is not Covered Software. - -1.8. “License” - - means this document. - -1.9. “Licensable” - - means having the right to grant, to the maximum extent possible, whether at the - time of the initial grant or subsequently, any and all of the rights conveyed by - this License. - -1.10. “Modifications” - - means any of the following: - - a. any file in Source Code Form that results from an addition to, deletion - from, or modification of the contents of Covered Software; or - - b. any new file in Source Code Form that contains any Covered Software. - -1.11. “Patent Claims” of a Contributor - - means any patent claim(s), including without limitation, method, process, - and apparatus claims, in any patent Licensable by such Contributor that - would be infringed, but for the grant of the License, by the making, - using, selling, offering for sale, having made, import, or transfer of - either its Contributions or its Contributor Version. - -1.12. “Secondary License” - - means either the GNU General Public License, Version 2.0, the GNU Lesser - General Public License, Version 2.1, the GNU Affero General Public - License, Version 3.0, or any later versions of those licenses. - -1.13. “Source Code Form” - - means the form of the work preferred for making modifications. - -1.14. “You” (or “Your”) - - means an individual or a legal entity exercising rights under this - License. For legal entities, “You” includes any entity that controls, is - controlled by, or is under common control with You. For purposes of this - definition, “control” means (a) the power, direct or indirect, to cause - the direction or management of such entity, whether by contract or - otherwise, or (b) ownership of more than fifty percent (50%) of the - outstanding shares or beneficial ownership of such entity. - - -2. License Grants and Conditions - -2.1. Grants - - Each Contributor hereby grants You a world-wide, royalty-free, - non-exclusive license: - - a. under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or as - part of a Larger Work; and - - b. under Patent Claims of such Contributor to make, use, sell, offer for - sale, have made, import, and otherwise transfer either its Contributions - or its Contributor Version. - -2.2. Effective Date - - The licenses granted in Section 2.1 with respect to any Contribution become - effective for each Contribution on the date the Contributor first distributes - such Contribution. - -2.3. Limitations on Grant Scope - - The licenses granted in this Section 2 are the only rights granted under this - License. No additional rights or licenses will be implied from the distribution - or licensing of Covered Software under this License. Notwithstanding Section - 2.1(b) above, no patent license is granted by a Contributor: - - a. for any code that a Contributor has removed from Covered Software; or - - b. for infringements caused by: (i) Your and any other third party’s - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - - c. under Patent Claims infringed by Covered Software in the absence of its - Contributions. - - This License does not grant any rights in the trademarks, service marks, or - logos of any Contributor (except as may be necessary to comply with the - notice requirements in Section 3.4). - -2.4. Subsequent Licenses - - No Contributor makes additional grants as a result of Your choice to - distribute the Covered Software under a subsequent version of this License - (see Section 10.2) or under the terms of a Secondary License (if permitted - under the terms of Section 3.3). - -2.5. Representation - - Each Contributor represents that the Contributor believes its Contributions - are its original creation(s) or it has sufficient rights to grant the - rights to its Contributions conveyed by this License. - -2.6. Fair Use - - This License is not intended to limit any rights You have under applicable - copyright doctrines of fair use, fair dealing, or other equivalents. - -2.7. Conditions - - Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in - Section 2.1. - - -3. Responsibilities - -3.1. Distribution of Source Form - - All distribution of Covered Software in Source Code Form, including any - Modifications that You create or to which You contribute, must be under the - terms of this License. You must inform recipients that the Source Code Form - of the Covered Software is governed by the terms of this License, and how - they can obtain a copy of this License. You may not attempt to alter or - restrict the recipients’ rights in the Source Code Form. - -3.2. Distribution of Executable Form - - If You distribute Covered Software in Executable Form then: - - a. such Covered Software must also be made available in Source Code Form, - as described in Section 3.1, and You must inform recipients of the - Executable Form how they can obtain a copy of such Source Code Form by - reasonable means in a timely manner, at a charge no more than the cost - of distribution to the recipient; and - - b. You may distribute such Executable Form under the terms of this License, - or sublicense it under different terms, provided that the license for - the Executable Form does not attempt to limit or alter the recipients’ - rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - - You may create and distribute a Larger Work under terms of Your choice, - provided that You also comply with the requirements of this License for the - Covered Software. If the Larger Work is a combination of Covered Software - with a work governed by one or more Secondary Licenses, and the Covered - Software is not Incompatible With Secondary Licenses, this License permits - You to additionally distribute such Covered Software under the terms of - such Secondary License(s), so that the recipient of the Larger Work may, at - their option, further distribute the Covered Software under the terms of - either this License or such Secondary License(s). - -3.4. Notices - - You may not remove or alter the substance of any license notices (including - copyright notices, patent notices, disclaimers of warranty, or limitations - of liability) contained within the Source Code Form of the Covered - Software, except that You may alter any license notices to the extent - required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - - You may choose to offer, and to charge a fee for, warranty, support, - indemnity or liability obligations to one or more recipients of Covered - Software. However, You may do so only on Your own behalf, and not on behalf - of any Contributor. You must make it absolutely clear that any such - warranty, support, indemnity, or liability obligation is offered by You - alone, and You hereby agree to indemnify every Contributor for any - liability incurred by such Contributor as a result of warranty, support, - indemnity or liability terms You offer. You may include additional - disclaimers of warranty and limitations of liability specific to any - jurisdiction. - -4. Inability to Comply Due to Statute or Regulation - - If it is impossible for You to comply with any of the terms of this License - with respect to some or all of the Covered Software due to statute, judicial - order, or regulation then You must: (a) comply with the terms of this License - to the maximum extent possible; and (b) describe the limitations and the code - they affect. Such description must be placed in a text file included with all - distributions of the Covered Software under this License. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Termination - -5.1. The rights granted under this License will terminate automatically if You - fail to comply with any of its terms. However, if You become compliant, - then the rights granted under this License from a particular Contributor - are reinstated (a) provisionally, unless and until such Contributor - explicitly and finally terminates Your grants, and (b) on an ongoing basis, - if such Contributor fails to notify You of the non-compliance by some - reasonable means prior to 60 days after You have come back into compliance. - Moreover, Your grants from a particular Contributor are reinstated on an - ongoing basis if such Contributor notifies You of the non-compliance by - some reasonable means, this is the first time You have received notice of - non-compliance with this License from such Contributor, and You become - compliant prior to 30 days after Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent - infringement claim (excluding declaratory judgment actions, counter-claims, - and cross-claims) alleging that a Contributor Version directly or - indirectly infringes any patent, then the rights granted to You by any and - all Contributors for the Covered Software under Section 2.1 of this License - shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user - license agreements (excluding distributors and resellers) which have been - validly granted by You or Your distributors under this License prior to - termination shall survive termination. - -6. Disclaimer of Warranty - - Covered Software is provided under this License on an “as is” basis, without - warranty of any kind, either expressed, implied, or statutory, including, - without limitation, warranties that the Covered Software is free of defects, - merchantable, fit for a particular purpose or non-infringing. The entire - risk as to the quality and performance of the Covered Software is with You. - Should any Covered Software prove defective in any respect, You (not any - Contributor) assume the cost of any necessary servicing, repair, or - correction. This disclaimer of warranty constitutes an essential part of this - License. No use of any Covered Software is authorized under this License - except under this disclaimer. - -7. Limitation of Liability - - Under no circumstances and under no legal theory, whether tort (including - negligence), contract, or otherwise, shall any Contributor, or anyone who - distributes Covered Software as permitted above, be liable to You for any - direct, indirect, special, incidental, or consequential damages of any - character including, without limitation, damages for lost profits, loss of - goodwill, work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses, even if such party shall have been - informed of the possibility of such damages. This limitation of liability - shall not apply to liability for death or personal injury resulting from such - party’s negligence to the extent applicable law prohibits such limitation. - Some jurisdictions do not allow the exclusion or limitation of incidental or - consequential damages, so this exclusion and limitation may not apply to You. - -8. Litigation - - Any litigation relating to this License may be brought only in the courts of - a jurisdiction where the defendant maintains its principal place of business - and such litigation shall be governed by laws of that jurisdiction, without - reference to its conflict-of-law provisions. Nothing in this Section shall - prevent a party’s ability to bring cross-claims or counter-claims. - -9. Miscellaneous - - This License represents the complete agreement concerning the subject matter - hereof. If any provision of this License is held to be unenforceable, such - provision shall be reformed only to the extent necessary to make it - enforceable. Any law or regulation which provides that the language of a - contract shall be construed against the drafter shall not be used to construe - this License against a Contributor. - - -10. Versions of the License - -10.1. New Versions - - Mozilla Foundation is the license steward. Except as provided in Section - 10.3, no one other than the license steward has the right to modify or - publish new versions of this License. Each version will be given a - distinguishing version number. - -10.2. Effect of New Versions - - You may distribute the Covered Software under the terms of the version of - the License under which You originally received the Covered Software, or - under the terms of any subsequent version published by the license - steward. - -10.3. Modified Versions - - If you create software not governed by this License, and you want to - create a new license for such software, you may create and use a modified - version of this License if you rename the license and remove any - references to the name of the license steward (except to note that such - modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses - If You choose to distribute Source Code Form that is Incompatible With - Secondary Licenses under the terms of this version of the License, the - notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice - - This Source Code Form is subject to the - terms of the Mozilla Public License, v. - 2.0. If a copy of the MPL was not - distributed with this file, You can - obtain one at - http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular file, then -You may include the notice in a location (such as a LICENSE file in a relevant -directory) where a recipient would be likely to look for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - “Incompatible With Secondary Licenses” Notice - - This Source Code Form is “Incompatible - With Secondary Licenses”, as defined by - the Mozilla Public License, v. 2.0. - diff --git a/vendor/github.com/d2g/dhcp4server/README.md b/vendor/github.com/d2g/dhcp4server/README.md deleted file mode 100644 index 92230542b..000000000 --- a/vendor/github.com/d2g/dhcp4server/README.md +++ /dev/null @@ -1,4 +0,0 @@ -dhcp4server [![GoDoc](https://godoc.org/github.com/d2g/dhcp4server?status.svg)](http://godoc.org/github.com/d2g/dhcp4server) [![Coverage Status](https://coveralls.io/repos/d2g/dhcp4server/badge.svg)](https://coveralls.io/r/d2g/dhcp4server) [![Codeship Status for d2g/dhcp4server](https://codeship.com/projects/ff96ded0-89cb-0132-8209-4635861fb902/status?branch=master)](https://codeship.com/projects/59804) -=========== - -DHCP Server diff --git a/vendor/github.com/d2g/dhcp4server/leasepool/lease.go b/vendor/github.com/d2g/dhcp4server/leasepool/lease.go deleted file mode 100644 index 98306eca1..000000000 --- a/vendor/github.com/d2g/dhcp4server/leasepool/lease.go +++ /dev/null @@ -1,102 +0,0 @@ -package leasepool - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "net" - "time" -) - -type LeaseStatus int - -const ( - Free LeaseStatus = 0 - Reserved LeaseStatus = 1 - Active LeaseStatus = 2 -) - -type Lease struct { - IP net.IP //The IP of the Lease - Status LeaseStatus //Are Reserved, Active or Free - MACAddress net.HardwareAddr //Mac Address of the Device - ClientID []byte //ClientID of the request - Hostname string //Hostname From option 12 - Expiry time.Time //Expiry Time -} - -//leaseMarshal is a mirror of Lease used for marshalling, since -//net.HardwareAddr has no native marshalling capability. -type leaseMarshal struct { - IP string - Status int - MACAddress string - ClientID string - Hostname string - Expiry time.Time -} - -func (this Lease) MarshalJSON() ([]byte, error) { - return json.Marshal(leaseMarshal{ - IP: this.IP.String(), - Status: int(this.Status), - MACAddress: this.MACAddress.String(), - ClientID: hex.EncodeToString(this.ClientID), - Hostname: this.Hostname, - Expiry: this.Expiry, - }) -} - -func (this *Lease) UnmarshalJSON(data []byte) error { - stringUnMarshal := leaseMarshal{} - err := json.Unmarshal(data, &stringUnMarshal) - if err != nil { - return err - } - - this.IP = net.ParseIP(stringUnMarshal.IP) - this.Status = LeaseStatus(stringUnMarshal.Status) - if stringUnMarshal.MACAddress != "" { - this.MACAddress, err = net.ParseMAC(stringUnMarshal.MACAddress) - if err != nil { - return fmt.Errorf("error parsing MAC address: %v", err) - } - } - this.ClientID, err = hex.DecodeString(stringUnMarshal.ClientID) - if err != nil { - return fmt.Errorf("error decoding clientID: %v", err) - } - this.Hostname = stringUnMarshal.Hostname - this.Expiry = stringUnMarshal.Expiry - - return nil -} - -func (this Lease) Equal(other Lease) bool { - if !this.IP.Equal(other.IP) { - return false - } - - if int(this.Status) != int(other.Status) { - return false - } - - if this.MACAddress.String() != other.MACAddress.String() { - return false - } - - if !bytes.Equal(this.ClientID, other.ClientID) { - return false - } - - if this.Hostname != other.Hostname { - return false - } - - if !this.Expiry.Equal(other.Expiry) { - return false - } - - return true -} diff --git a/vendor/github.com/d2g/dhcp4server/leasepool/leasepool.go b/vendor/github.com/d2g/dhcp4server/leasepool/leasepool.go deleted file mode 100644 index a620b4b92..000000000 --- a/vendor/github.com/d2g/dhcp4server/leasepool/leasepool.go +++ /dev/null @@ -1,49 +0,0 @@ -package leasepool - -import ( - "net" -) - -/* - * Lease.IP is the Key. - */ -type LeasePool interface { - //Add A Lease To The Pool - AddLease(Lease) error - - //Remove - RemoveLease(net.IP) error - - //Remove All Leases from the Pool (Required for Persistant LeaseManagers) - PurgeLeases() error - - /* - * Get the Lease - * -Found - * -Copy Of the Lease - * -Any Error - */ - GetLease(net.IP) (bool, Lease, error) - - //Get the lease already in use by that hardware address and/or client identifier. - GetLeaseForClient(net.HardwareAddr, []byte) (bool, Lease, error) - - /* - * -Lease Available - * -Lease - * -Error - */ - GetNextFreeLease() (bool, Lease, error) - - /* - * Return All Leases - */ - GetLeases() ([]Lease, error) - - /* - * Update Lease - * - Has Updated - * - Error - */ - UpdateLease(Lease) (bool, error) -} diff --git a/vendor/github.com/d2g/dhcp4server/leasepool/memorypool/memorypool.go b/vendor/github.com/d2g/dhcp4server/leasepool/memorypool/memorypool.go deleted file mode 100644 index 7cd8d2d5a..000000000 --- a/vendor/github.com/d2g/dhcp4server/leasepool/memorypool/memorypool.go +++ /dev/null @@ -1,161 +0,0 @@ -package memorypool - -import ( - "bytes" - "errors" - "github.com/d2g/dhcp4server/leasepool" - "net" - "sync" -) - -type MemoryPool struct { - pool []leasepool.Lease - poolLock sync.Mutex -} - -//Add A Lease To The Pool -func (t *MemoryPool) AddLease(newLease leasepool.Lease) error { - t.poolLock.Lock() - defer t.poolLock.Unlock() - - if t.pool == nil { - t.pool = make([]leasepool.Lease, 0) - } - - for i := range t.pool { - if t.pool[i].IP.Equal(newLease.IP) { - //Lease Already Exists In Pool - return errors.New("Error: Lease IP \"" + newLease.IP.String() + "\" alreay exists in Pool") - } - } - - t.pool = append([]leasepool.Lease{newLease}, t.pool...) - return nil -} - -//Remove a Lease From The Pool -func (t *MemoryPool) RemoveLease(leaseIP net.IP) error { - t.poolLock.Lock() - defer t.poolLock.Unlock() - - for i := range t.pool { - if t.pool[i].IP.Equal(leaseIP) { - - //Move the Last Element to This Position. - t.pool[i] = t.pool[len(t.pool)-1] - - //Shortern the Pool By One. - t.pool = t.pool[0:(len(t.pool) - 1)] - return nil - } - } - - return errors.New("Error: Lease IP \"" + leaseIP.String() + "\" Is Not In The Pool") -} - -//Remove All Leases from the Pool (Required for Persistant LeaseManagers) -func (t *MemoryPool) PurgeLeases() error { - t.poolLock.Lock() - defer t.poolLock.Unlock() - - t.pool = nil - t.pool = make([]leasepool.Lease, 0) - return nil -} - -/* - * Get the Lease - * -Found - * -Copy Of the Lease - * -Any Error - */ -func (t *MemoryPool) GetLease(leaseIP net.IP) (bool, leasepool.Lease, error) { - t.poolLock.Lock() - defer t.poolLock.Unlock() - - for i := range t.pool { - if t.pool[i].IP.Equal(leaseIP) { - return true, t.pool[i], nil - } - } - return false, leasepool.Lease{}, nil -} - -func makeKey(macAddress net.HardwareAddr, clientID []byte) []byte { - key := []byte(macAddress) - if len(clientID) > 0 { - key = append(key, clientID...) - } - return key -} - -//Get the lease already in use by that hardware address and/or client identifier. -func (t *MemoryPool) GetLeaseForClient(macAddress net.HardwareAddr, clientID []byte) (bool, leasepool.Lease, error) { - t.poolLock.Lock() - defer t.poolLock.Unlock() - - needleKey := makeKey(macAddress, clientID) - for i := range t.pool { - haystackKey := makeKey(t.pool[i].MACAddress, t.pool[i].ClientID) - if bytes.Equal(needleKey, haystackKey) { - return true, t.pool[i], nil - } - } - return false, leasepool.Lease{}, nil -} - -/* - * -Lease Available - * -Lease - * -Error - */ -func (t *MemoryPool) GetNextFreeLease() (bool, leasepool.Lease, error) { - t.poolLock.Lock() - defer t.poolLock.Unlock() - - //Loop Through the elements backwards. - for i := (len(t.pool) - 1); i >= 0; i-- { - //If the Lease Is Free - if t.pool[i].Status == leasepool.Free { - //Take the Element - iLease := t.pool[i] - //Shrink the Pool By 1 - t.pool = t.pool[:(len(t.pool) - 1)] - //Place the Lease At the Begining (This saves us having some sort of counter...) - t.pool = append([]leasepool.Lease{iLease}, t.pool...) - return true, iLease, nil - } - } - return false, leasepool.Lease{}, nil -} - -/* - * Return All Leases - */ -func (t *MemoryPool) GetLeases() ([]leasepool.Lease, error) { - return t.pool, nil -} - -/* - * Update Lease - * - Has Updated - * - Error - */ -func (t *MemoryPool) UpdateLease(lease leasepool.Lease) (bool, error) { - t.poolLock.Lock() - defer t.poolLock.Unlock() - - for i := range t.pool { - if t.pool[i].IP.Equal(lease.IP) { - - t.pool[i].MACAddress = lease.MACAddress - t.pool[i].ClientID = lease.ClientID - t.pool[i].Hostname = lease.Hostname - t.pool[i].Expiry = lease.Expiry - t.pool[i].Status = lease.Status - - return true, nil - } - } - return false, nil -} diff --git a/vendor/github.com/d2g/dhcp4server/server.go b/vendor/github.com/d2g/dhcp4server/server.go deleted file mode 100644 index 7b1d374d9..000000000 --- a/vendor/github.com/d2g/dhcp4server/server.go +++ /dev/null @@ -1,590 +0,0 @@ -package dhcp4server - -import ( - "bytes" - "errors" - "log" - "net" - "sync/atomic" - "time" - - "github.com/d2g/dhcp4" - "github.com/d2g/dhcp4server/leasepool" - - "golang.org/x/net/ipv4" -) - -/* - * The DHCP Server Structure - */ -type Server struct { - //Configuration Options - ip net.IP //The IP Address We Tell Clients The Server Is On. - defaultGateway net.IP //The Default Gateway Address - dnsServers []net.IP //DNS Servers - subnetMask net.IP //ie. 255.255.255.0 - leaseDuration time.Duration //Number of Seconds - ignoreIPs []net.IP //Slice of IP's that should be ignored by the Server. - ignoreHardwareAddress []net.HardwareAddr //Slice of Hardware Addresses we should ignore. - - //Local Address - laddr net.UDPAddr - - //Remote address - raddr net.UDPAddr - - //LeasePool - leasePool leasepool.LeasePool //Lease Pool Manager - - //Used to Gracefully Close the Server - shutdown uint32 - //Listeners & Response Connection. - connection *ipv4.PacketConn -} - -// Create A New Server -func New(ip net.IP, l leasepool.LeasePool, options ...func(*Server) error) (*Server, error) { - s := Server{ - ip: ip, - defaultGateway: ip, - dnsServers: []net.IP{net.IPv4(208, 67, 222, 222), net.IPv4(208, 67, 220, 220)}, //OPENDNS - subnetMask: net.IPv4(255, 255, 255, 0), - leaseDuration: 24 * time.Hour, - leasePool: l, - laddr: net.UDPAddr{IP: net.IPv4(0, 0, 0, 0), Port: 67}, - raddr: net.UDPAddr{IP: net.IPv4bcast, Port: 68}, - } - - err := s.setOptions(options...) - if err != nil { - return &s, err - } - - return &s, err -} - -func (s *Server) setOptions(options ...func(*Server) error) error { - for _, opt := range options { - if err := opt(s); err != nil { - return err - } - } - return nil -} - -// Set the Server IP -func IP(i net.IP) func(*Server) error { - return func(s *Server) error { - s.ip = i - return nil - } - return nil -} - -// Set the Default Gateway Address. -func DefaultGateway(r net.IP) func(*Server) error { - return func(s *Server) error { - s.defaultGateway = r - return nil - } -} - -// Set the DNS servers. -func DNSServers(dnss []net.IP) func(*Server) error { - return func(s *Server) error { - s.dnsServers = dnss - return nil - } -} - -// Set the Subnet Mask -func SubnetMask(m net.IP) func(*Server) error { - return func(s *Server) error { - s.subnetMask = m - return nil - } -} - -// Set Lease Duration -func LeaseDuration(d time.Duration) func(*Server) error { - return func(s *Server) error { - s.leaseDuration = d - return nil - } -} - -// Set Ignore IPs -func IgnoreIPs(ips []net.IP) func(*Server) error { - return func(s *Server) error { - s.ignoreIPs = ips - return nil - } -} - -// Set Ignore Hardware Addresses -func IgnoreHardwareAddresses(h []net.HardwareAddr) func(*Server) error { - return func(s *Server) error { - s.ignoreHardwareAddress = h - return nil - } -} - -// Set LeasePool -func LeasePool(p leasepool.LeasePool) func(*Server) error { - return func(s *Server) error { - s.leasePool = p - return nil - } -} - -// Set The Local Address -func SetLocalAddr(a net.UDPAddr) func(*Server) error { - return func(s *Server) error { - s.laddr = a - return nil - } -} - -// Set The Remote Address -func SetRemoteAddr(a net.UDPAddr) func(*Server) error { - return func(s *Server) error { - s.raddr = a - return nil - } -} - -/* - * Start The DHCP Server - */ -func (s *Server) ListenAndServe() error { - var err error - - connection, err := net.ListenPacket("udp4", s.laddr.String()) - if err != nil { - log.Printf("Debug: Error Returned From ListenPacket On \"%s\" Because of \"%s\"\n", s.laddr.String(), err.Error()) - return err - } - s.connection = ipv4.NewPacketConn(connection) - defer s.connection.Close() - - //We Currently Don't Use this Feature Which is the only bit that is Linux Only. - //if err := s.connection.SetControlMessage(ipv4.FlagInterface, true); err != nil { - // return err - //} - - log.Println("Trace: DHCP Server Listening.") - - for { - ListenForDHCPPackets: - if s.shouldShutdown() { - return nil - } - - //Make Our Buffer (Max Buffer is 574) "I believe this 576 size comes from RFC 791" - Random Mailing list quote of the day. - buffer := make([]byte, 576) - - //Set Read Deadline - s.connection.SetReadDeadline(time.Now().Add(time.Second)) - // Read Packet - n, control_message, source, err := s.connection.ReadFrom(buffer) - - if err != nil { - - switch v := err.(type) { - case *net.OpError: - // If we've been signaled to shut down, ignore - // the "use of closed network connection" error - // since the connection was closed by the - // shutdown request - if s.shouldShutdown() { - return nil - } - if v.Timeout() { - goto ListenForDHCPPackets - } - case *net.AddrError: - if v.Timeout() { - goto ListenForDHCPPackets - } - case *net.UnknownNetworkError: - if v.Timeout() { - goto ListenForDHCPPackets - } - } - - log.Printf("Debug: Unexpect Error from Connection Read From: %v\n", err) - return err - } - - //We seem to have an issue with undersized packets? - if n < 240 { - log.Printf("Error: Invalid Packet Size \"%d\" Received:%v\n", n, buffer[:n]) - continue - } - - //We should ignore some requests - //It shouldn't be possible to ignore IP's because they shouldn't have them as we're the DHCP server. - //However, they can have i.e. if you're the client & server :S. - for _, ipToIgnore := range s.ignoreIPs { - if ipToIgnore.Equal(source.(*net.UDPAddr).IP) { - log.Println("Debug: Ignoring DHCP Request From IP:" + ipToIgnore.String()) - continue - } - } - - packet := dhcp4.Packet(buffer[:n]) - - //We can ignore hardware addresses. - //Usefull for ignoring a range of hardware addresses - for _, hardwareAddressToIgnore := range s.ignoreHardwareAddress { - if bytes.Equal(hardwareAddressToIgnore, packet.CHAddr()) { - log.Println("Debug: Ignoring DHCP Request From Hardware Address:" + hardwareAddressToIgnore.String()) - continue - } - } - - log.Printf("Trace: Packet Received ID:%v\n", packet.XId()) - log.Printf("Trace: Packet Options:%v\n", packet.ParseOptions()) - log.Printf("Trace: Packet Client IP : %v\n", packet.CIAddr().String()) - log.Printf("Trace: Packet Your IP : %v\n", packet.YIAddr().String()) - log.Printf("Trace: Packet Server IP : %v\n", packet.SIAddr().String()) - log.Printf("Trace: Packet Gateway IP: %v\n", packet.GIAddr().String()) - log.Printf("Trace: Packet Client Mac: %v\n", packet.CHAddr().String()) - - //We need to stop butting in with other servers. - if packet.SIAddr().Equal(net.IPv4(0, 0, 0, 0)) || packet.SIAddr().Equal(net.IP{}) || packet.SIAddr().Equal(s.ip) { - - returnPacket, err := s.ServeDHCP(packet) - if err != nil { - log.Println("Debug: Error Serving DHCP:" + err.Error()) - return err - } - - if len(returnPacket) > 0 { - log.Printf("Trace: Packet Returned ID:%v\n", returnPacket.XId()) - log.Printf("Trace: Packet Options:%v\n", returnPacket.ParseOptions()) - log.Printf("Trace: Packet Client IP : %v\n", returnPacket.CIAddr().String()) - log.Printf("Trace: Packet Your IP : %v\n", returnPacket.YIAddr().String()) - log.Printf("Trace: Packet Server IP : %v\n", returnPacket.SIAddr().String()) - log.Printf("Trace: Packet Gateway IP: %v\n", returnPacket.GIAddr().String()) - log.Printf("Trace: Packet Client Mac: %v\n", returnPacket.CHAddr().String()) - - _, err = s.connection.WriteTo(returnPacket, control_message, &s.raddr) - if err != nil { - log.Println("Debug: Error Writing:" + err.Error()) - return err - } - } - } - - } -} - -func getClientID(packetOptions dhcp4.Options) []byte { - if clientID, ok := packetOptions[dhcp4.OptionClientIdentifier]; ok { - return clientID - } - return nil -} - -func (s *Server) ServeDHCP(packet dhcp4.Packet) (dhcp4.Packet, error) { - packetOptions := packet.ParseOptions() - - switch dhcp4.MessageType(packetOptions[dhcp4.OptionDHCPMessageType][0]) { - case dhcp4.Discover: - - //Discover Received from client - //Lets get the lease we're going to send them - found, lease, err := s.GetLease(packet) - if err != nil { - return dhcp4.Packet{}, err - } - - if !found { - log.Println("Warning: It Looks Like Our Leases Are Depleted...") - return dhcp4.Packet{}, nil - } - - offerPacket := s.OfferPacket(packet) - offerPacket.SetYIAddr(lease.IP) - - //Sort out the packet options - offerPacket.PadToMinSize() - - lease.Status = leasepool.Reserved - lease.MACAddress = packet.CHAddr() - lease.ClientID = getClientID(packetOptions) - - //If the lease expires within the next 5 Mins increase the lease expiary (Giving the Client 5 mins to complete) - if lease.Expiry.Before(time.Now().Add(time.Minute * 5)) { - lease.Expiry = time.Now().Add(time.Minute * 5) - } - - if packetOptions[dhcp4.OptionHostName] != nil && string(packetOptions[dhcp4.OptionHostName]) != "" { - lease.Hostname = string(packetOptions[dhcp4.OptionHostName]) - } - - updated, err := s.leasePool.UpdateLease(lease) - if err != nil { - return dhcp4.Packet{}, err - } - - if !updated { - //Unable to reserve lease (It's now active else where maybe?) - return dhcp4.Packet{}, errors.New("Unable to Reserve Lease:" + lease.IP.String()) - } - - return offerPacket, nil - case dhcp4.Request: - //Request Received from client - //Lets get the lease we're going to send them - found, lease, err := s.GetLease(packet) - if err != nil { - return dhcp4.Packet{}, err - } - - if !found { - log.Println("Warning: It Looks Like Our Leases Are Depleted...") - return dhcp4.Packet{}, nil - } - - //If the lease is not the one requested We should send a NAK.. - if len(packetOptions) > 0 && !net.IP(packetOptions[dhcp4.OptionRequestedIPAddress]).Equal(lease.IP) { - //NAK - declinePacket := s.DeclinePacket(packet) - declinePacket.PadToMinSize() - - return declinePacket, nil - } else { - lease.Status = leasepool.Active - lease.MACAddress = packet.CHAddr() - lease.ClientID = getClientID(packetOptions) - - lease.Expiry = time.Now().Add(s.leaseDuration) - - if packetOptions[dhcp4.OptionHostName] != nil && string(packetOptions[dhcp4.OptionHostName]) != "" { - lease.Hostname = string(packetOptions[dhcp4.OptionHostName]) - } - - updated, err := s.leasePool.UpdateLease(lease) - if err != nil { - return dhcp4.Packet{}, err - } - - if updated { - //ACK - acknowledgementPacket := s.AcknowledgementPacket(packet) - acknowledgementPacket.SetYIAddr(lease.IP) - - //Lease time. - acknowledgementPacket.AddOption(dhcp4.OptionIPAddressLeaseTime, dhcp4.OptionsLeaseTime(lease.Expiry.Sub(time.Now()))) - acknowledgementPacket.PadToMinSize() - - return acknowledgementPacket, nil - } else { - //NAK - declinePacket := s.DeclinePacket(packet) - declinePacket.PadToMinSize() - - return declinePacket, nil - } - } - case dhcp4.Decline: - //Decline from the client: - log.Printf("Debug: Decline Message:%v\n", packet) - - case dhcp4.Release: - //Decline from the client: - log.Printf("Debug: Release Message:%v\n", packet) - - default: - log.Printf("Debug: Unexpected Packet Type:%v\n", dhcp4.MessageType(packetOptions[dhcp4.OptionDHCPMessageType][0])) - } - - return dhcp4.Packet{}, nil -} - -/* - * Create DHCP Offer Packet - */ -func (s *Server) OfferPacket(discoverPacket dhcp4.Packet) dhcp4.Packet { - - offerPacket := dhcp4.NewPacket(dhcp4.BootReply) - offerPacket.SetXId(discoverPacket.XId()) - offerPacket.SetFlags(discoverPacket.Flags()) - - offerPacket.SetCHAddr(discoverPacket.CHAddr()) - offerPacket.SetGIAddr(discoverPacket.GIAddr()) - offerPacket.SetSecs(discoverPacket.Secs()) - - //53 - offerPacket.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(dhcp4.Offer)}) - //54 - offerPacket.AddOption(dhcp4.OptionServerIdentifier, s.ip.To4()) - //51 - offerPacket.AddOption(dhcp4.OptionIPAddressLeaseTime, dhcp4.OptionsLeaseTime(s.leaseDuration)) - - //Other options go in requested order... - discoverPacketOptions := discoverPacket.ParseOptions() - - ourOptions := make(dhcp4.Options) - - //1 - ourOptions[dhcp4.OptionSubnetMask] = s.subnetMask.To4() - //3 - ourOptions[dhcp4.OptionRouter] = s.defaultGateway.To4() - //6 - ourOptions[dhcp4.OptionDomainNameServer] = dhcp4.JoinIPs(s.dnsServers) - - if discoverPacketOptions[dhcp4.OptionParameterRequestList] != nil { - //Loop through the requested options and if we have them add them. - for _, optionCode := range discoverPacketOptions[dhcp4.OptionParameterRequestList] { - if !bytes.Equal(ourOptions[dhcp4.OptionCode(optionCode)], []byte{}) { - offerPacket.AddOption(dhcp4.OptionCode(optionCode), ourOptions[dhcp4.OptionCode(optionCode)]) - delete(ourOptions, dhcp4.OptionCode(optionCode)) - } - } - } - - //Add all the options not requested. - for optionCode, optionValue := range ourOptions { - offerPacket.AddOption(optionCode, optionValue) - } - - return offerPacket - -} - -/* - * Create DHCP Acknowledgement - */ -func (s *Server) AcknowledgementPacket(requestPacket dhcp4.Packet) dhcp4.Packet { - - acknowledgementPacket := dhcp4.NewPacket(dhcp4.BootReply) - acknowledgementPacket.SetXId(requestPacket.XId()) - acknowledgementPacket.SetFlags(requestPacket.Flags()) - - acknowledgementPacket.SetGIAddr(requestPacket.GIAddr()) - acknowledgementPacket.SetCHAddr(requestPacket.CHAddr()) - acknowledgementPacket.SetSecs(requestPacket.Secs()) - - acknowledgementPacket.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(dhcp4.ACK)}) - acknowledgementPacket.AddOption(dhcp4.OptionSubnetMask, s.subnetMask.To4()) - acknowledgementPacket.AddOption(dhcp4.OptionRouter, s.defaultGateway.To4()) - acknowledgementPacket.AddOption(dhcp4.OptionDomainNameServer, dhcp4.JoinIPs(s.dnsServers)) - acknowledgementPacket.AddOption(dhcp4.OptionServerIdentifier, s.ip.To4()) - - return acknowledgementPacket -} - -/* - * Create DHCP Decline - */ -func (s *Server) DeclinePacket(requestPacket dhcp4.Packet) dhcp4.Packet { - - declinePacket := dhcp4.NewPacket(dhcp4.BootReply) - declinePacket.SetXId(requestPacket.XId()) - declinePacket.SetFlags(requestPacket.Flags()) - - declinePacket.SetGIAddr(requestPacket.GIAddr()) - declinePacket.SetCHAddr(requestPacket.CHAddr()) - declinePacket.SetSecs(requestPacket.Secs()) - - declinePacket.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(dhcp4.NAK)}) - declinePacket.AddOption(dhcp4.OptionSubnetMask, s.subnetMask.To4()) - declinePacket.AddOption(dhcp4.OptionRouter, s.defaultGateway.To4()) - declinePacket.AddOption(dhcp4.OptionDomainNameServer, dhcp4.JoinIPs(s.dnsServers)) - declinePacket.AddOption(dhcp4.OptionServerIdentifier, s.ip.To4()) - - return declinePacket -} - -/* - * Get Lease tries to work out the best lease for the packet supplied. - * Taking into account all Requested IP, Exisitng MACAddresses and Free leases. - */ -func (s *Server) GetLease(packet dhcp4.Packet) (found bool, lease leasepool.Lease, err error) { - packetOptions := packet.ParseOptions() - - clientID := getClientID(packetOptions) - - //Requested an IP - if (len(packetOptions) > 0) && - packetOptions[dhcp4.OptionRequestedIPAddress] != nil && - !net.IP(packetOptions[dhcp4.OptionRequestedIPAddress]).Equal(net.IP{}) { - //An IP Has Been Requested Let's Try and Get that One. - - found, lease, err = s.leasePool.GetLease(net.IP(packetOptions[dhcp4.OptionRequestedIPAddress])) - if err != nil { - return - } - - if found { - //If lease is free, return it to client. If it is not - //free match against the MAC address and client - //identifier. - if lease.Status == leasepool.Free { - //Lease Is Free you Can Have it. - return - } - if bytes.Equal(lease.MACAddress, packet.CHAddr()) && - bytes.Equal(lease.ClientID, clientID) { - //Lease isn't free but it's yours - return - } - } - } - - //Ok Even if you requested an IP you can't have it. - found, lease, err = s.leasePool.GetLeaseForClient(packet.CHAddr(), clientID) - if found || err != nil { - return - } - - //Just get the next free lease if you can. - found, lease, err = s.leasePool.GetNextFreeLease() - return -} - -/* - * Shutdown The Server Gracefully - */ -func (s *Server) Shutdown() { - atomic.StoreUint32(&s.shutdown, 1) - s.connection.Close() -} - -func (s *Server) shouldShutdown() bool { - return atomic.LoadUint32(&s.shutdown) == 1 -} - -/* - * Garbage Collection - * Run Garbage Collection On Your Leases To Free Expired Leases. - */ -func (s *Server) GC() error { - leases, err := s.leasePool.GetLeases() - if err != nil { - return err - } - - for i := range leases { - if leases[i].Status != leasepool.Free { - //Lease Is Not Free - - if time.Now().After(leases[i].Expiry) { - //Lease has expired. - leases[i].Status = leasepool.Free - updated, err := s.leasePool.UpdateLease(leases[i]) - if err != nil { - log.Printf("Warning: Error trying to Free Lease %s \"%v\"\n", leases[i].IP.To4().String(), err) - } - if !updated { - log.Printf("Warning: Unable to Free Lease %s\n", leases[i].IP.To4().String()) - } - continue - } - } - } - return nil -} diff --git a/vendor/github.com/insomniacslk/dhcp/CONTRIBUTORS.md b/vendor/github.com/insomniacslk/dhcp/CONTRIBUTORS.md new file mode 100644 index 000000000..a43fa7942 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/CONTRIBUTORS.md @@ -0,0 +1,10 @@ +## Contributors + +* Andrea Barberio (main author) +* Pablo Mazzini (tons of fixes and new options) +* Sean Karlage (BSDP package, and of tons of improvements to the DHCPv4 package) +* Owen Mooney (several option fixes and modifiers) +* Mikolaj Walczak (asynchronous DHCPv6 client) +* Chris Koch (tons of improvements in DHCPv4 and DHCPv6 internals and interface) +* Akshay Navale, Brandon Bennett and Chris Gorham (ZTPv6 and ZTPv4 packages) +* Anatole Denis (tons of fixes and new options) diff --git a/vendor/github.com/insomniacslk/dhcp/LICENSE b/vendor/github.com/insomniacslk/dhcp/LICENSE new file mode 100644 index 000000000..c43d60d83 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2018, Andrea Barberio +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/bindtointerface.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/bindtointerface.go new file mode 100644 index 000000000..dbe8fbcd9 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/bindtointerface.go @@ -0,0 +1,10 @@ +package dhcpv4 + +import ( + "github.com/insomniacslk/dhcp/interfaces" +) + +// BindToInterface (deprecated) redirects to interfaces.BindToInterface +func BindToInterface(fd int, ifname string) error { + return interfaces.BindToInterface(fd, ifname) +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/defaults.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/defaults.go new file mode 100644 index 000000000..4faec2cc3 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/defaults.go @@ -0,0 +1,6 @@ +package dhcpv4 + +const ( + ServerPort = 67 + ClientPort = 68 +) diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go new file mode 100644 index 000000000..a87543121 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/dhcpv4.go @@ -0,0 +1,856 @@ +// Package dhcpv4 provides encoding and decoding of DHCPv4 packets and options. +// +// Example Usage: +// +// p, err := dhcpv4.New( +// dhcpv4.WithClientIP(net.IP{192, 168, 0, 1}), +// dhcpv4.WithMessageType(dhcpv4.MessageTypeInform), +// ) +// p.UpdateOption(dhcpv4.OptServerIdentifier(net.IP{192, 110, 110, 110})) +// +// // Retrieve the DHCP Message Type option. +// m := p.MessageType() +// +// bytesOnTheWire := p.ToBytes() +// longSummary := p.Summary() +package dhcpv4 + +import ( + "bytes" + "context" + "errors" + "fmt" + "net" + "strings" + "time" + + "github.com/insomniacslk/dhcp/iana" + "github.com/insomniacslk/dhcp/rfc1035label" + "github.com/u-root/uio/rand" + "github.com/u-root/uio/uio" +) + +const ( + // minPacketLen is the minimum DHCP header length. + minPacketLen = 236 + + // MaxHWAddrLen is the maximum hardware address length of the ClientHWAddr + // (client hardware address) according to RFC 2131, Section 2. This is the + // link-layer destination a server must send responses to. + MaxHWAddrLen = 16 + + // MaxMessageSize is the maximum size in bytes that a DHCPv4 packet can hold. + MaxMessageSize = 576 + + // Per RFC 951, the minimum length of a packet is 300 bytes. + bootpMinLen = 300 +) + +// RandomTimeout is the amount of time to wait until random number generation +// is canceled. +var RandomTimeout = 2 * time.Minute + +// magicCookie is the magic 4-byte value at the beginning of the list of options +// in a DHCPv4 packet. +var magicCookie = [4]byte{99, 130, 83, 99} + +// DHCPv4 represents a DHCPv4 packet header and options. See the New* functions +// to build DHCPv4 packets. +type DHCPv4 struct { + OpCode OpcodeType + HWType iana.HWType + HopCount uint8 + TransactionID TransactionID + NumSeconds uint16 + Flags uint16 + ClientIPAddr net.IP + YourIPAddr net.IP + ServerIPAddr net.IP + GatewayIPAddr net.IP + ClientHWAddr net.HardwareAddr + ServerHostName string + BootFileName string + Options Options +} + +// Modifier defines the signature for functions that can modify DHCPv4 +// structures. This is used to simplify packet manipulation +type Modifier func(d *DHCPv4) + +// IPv4AddrsForInterface obtains the currently-configured, non-loopback IPv4 +// addresses for iface. +func IPv4AddrsForInterface(iface *net.Interface) ([]net.IP, error) { + if iface == nil { + return nil, errors.New("IPv4AddrsForInterface: iface cannot be nil") + } + addrs, err := iface.Addrs() + if err != nil { + return nil, err + } + return GetExternalIPv4Addrs(addrs) +} + +// GetExternalIPv4Addrs obtains the currently-configured, non-loopback IPv4 +// addresses from `addrs` coming from a particular interface (e.g. +// net.Interface.Addrs). +func GetExternalIPv4Addrs(addrs []net.Addr) ([]net.IP, error) { + var v4addrs []net.IP + for _, addr := range addrs { + var ip net.IP + switch v := addr.(type) { + case *net.IPAddr: + ip = v.IP + case *net.IPNet: + ip = v.IP + } + + if ip == nil || ip.IsLoopback() { + continue + } + ip = ip.To4() + if ip == nil { + continue + } + v4addrs = append(v4addrs, ip) + } + return v4addrs, nil +} + +// GenerateTransactionID generates a random 32-bits number suitable for use as +// TransactionID +func GenerateTransactionID() (TransactionID, error) { + var xid TransactionID + ctx, cancel := context.WithTimeout(context.Background(), RandomTimeout) + defer cancel() + n, err := rand.ReadContext(ctx, xid[:]) + if err != nil { + return xid, fmt.Errorf("could not get random number: %v", err) + } + if n != 4 { + return xid, errors.New("invalid random sequence for transaction ID: smaller than 32 bits") + } + return xid, err +} + +// New creates a new DHCPv4 structure and fill it up with default values. It +// won't be a valid DHCPv4 message so you will need to adjust its fields. +// See also NewDiscovery, NewRequest, NewAcknowledge, NewInform and NewRelease. +func New(modifiers ...Modifier) (*DHCPv4, error) { + xid, err := GenerateTransactionID() + if err != nil { + return nil, err + } + d := DHCPv4{ + OpCode: OpcodeBootRequest, + HWType: iana.HWTypeEthernet, + ClientHWAddr: make(net.HardwareAddr, 6), + HopCount: 0, + TransactionID: xid, + NumSeconds: 0, + Flags: 0, + ClientIPAddr: net.IPv4zero, + YourIPAddr: net.IPv4zero, + ServerIPAddr: net.IPv4zero, + GatewayIPAddr: net.IPv4zero, + Options: make(Options), + } + for _, mod := range modifiers { + mod(&d) + } + return &d, nil +} + +// NewDiscoveryForInterface builds a new DHCPv4 Discovery message, with a default +// Ethernet HW type and the hardware address obtained from the specified +// interface. +func NewDiscoveryForInterface(ifname string, modifiers ...Modifier) (*DHCPv4, error) { + iface, err := net.InterfaceByName(ifname) + if err != nil { + return nil, err + } + return NewDiscovery(iface.HardwareAddr, modifiers...) +} + +// NewDiscovery builds a new DHCPv4 Discovery message, with a default Ethernet +// HW type and specified hardware address. +func NewDiscovery(hwaddr net.HardwareAddr, modifiers ...Modifier) (*DHCPv4, error) { + return New(PrependModifiers(modifiers, + WithHwAddr(hwaddr), + WithRequestedOptions( + OptionSubnetMask, + OptionRouter, + OptionDomainName, + OptionDomainNameServer, + ), + WithMessageType(MessageTypeDiscover), + )...) +} + +// NewInformForInterface builds a new DHCPv4 Informational message with default +// Ethernet HW type and the hardware address obtained from the specified +// interface. +func NewInformForInterface(ifname string, needsBroadcast bool) (*DHCPv4, error) { + // get hw addr + iface, err := net.InterfaceByName(ifname) + if err != nil { + return nil, err + } + + // Set Client IP as iface's currently-configured IP. + localIPs, err := IPv4AddrsForInterface(iface) + if err != nil || len(localIPs) == 0 { + return nil, fmt.Errorf("could not get local IPs for iface %s", ifname) + } + pkt, err := NewInform(iface.HardwareAddr, localIPs[0]) + if err != nil { + return nil, err + } + + if needsBroadcast { + pkt.SetBroadcast() + } else { + pkt.SetUnicast() + } + return pkt, nil +} + +// PrependModifiers prepends other to m. +func PrependModifiers(m []Modifier, other ...Modifier) []Modifier { + return append(other, m...) +} + +// NewInform builds a new DHCPv4 Informational message with the specified +// hardware address. +func NewInform(hwaddr net.HardwareAddr, localIP net.IP, modifiers ...Modifier) (*DHCPv4, error) { + return New(PrependModifiers(modifiers, + WithHwAddr(hwaddr), + WithMessageType(MessageTypeInform), + WithClientIP(localIP), + )...) +} + +// NewRequestFromOffer builds a DHCPv4 request from an offer. +// It assumes the SELECTING state by default, see Section 4.3.2 in RFC 2131 for more details. +func NewRequestFromOffer(offer *DHCPv4, modifiers ...Modifier) (*DHCPv4, error) { + return New(PrependModifiers(modifiers, + WithReply(offer), + WithMessageType(MessageTypeRequest), + WithClientIP(offer.ClientIPAddr), + WithOption(OptRequestedIPAddress(offer.YourIPAddr)), + // This is usually the server IP. + WithOptionCopied(offer, OptionServerIdentifier), + WithRequestedOptions( + OptionSubnetMask, + OptionRouter, + OptionDomainName, + OptionDomainNameServer, + ), + )...) +} + +// NewRenewFromAck builds a DHCPv4 RENEW-style request from the ACK of a lease. RENEW requests have +// minor changes to their options compared to SELECT requests as specified by RFC 2131, section 4.3.2. +func NewRenewFromAck(ack *DHCPv4, modifiers ...Modifier) (*DHCPv4, error) { + return New(PrependModifiers(modifiers, + WithReply(ack), + WithMessageType(MessageTypeRequest), + // The client IP must be filled in with the IP offered to the client + WithClientIP(ack.YourIPAddr), + // The renewal request must use unicast + WithBroadcast(false), + WithRequestedOptions( + OptionSubnetMask, + OptionRouter, + OptionDomainName, + OptionDomainNameServer, + ), + )...) +} + +// NewReplyFromRequest builds a DHCPv4 reply from a request. +func NewReplyFromRequest(request *DHCPv4, modifiers ...Modifier) (*DHCPv4, error) { + return New(PrependModifiers(modifiers, + WithReply(request), + WithGatewayIP(request.GatewayIPAddr), + WithOptionCopied(request, OptionRelayAgentInformation), + + // RFC 6842 states the Client Identifier option must be copied + // from the request if a client specified it. + WithOptionCopied(request, OptionClientIdentifier), + )...) +} + +// NewReleaseFromACK creates a DHCPv4 Release message from ACK. +// default Release message without any Modifer is created as following: +// - option Message Type is Release +// - ClientIP is set to ack.YourIPAddr +// - ClientHWAddr is set to ack.ClientHWAddr +// - Unicast +// - option Server Identifier is set to ack's ServerIdentifier +func NewReleaseFromACK(ack *DHCPv4, modifiers ...Modifier) (*DHCPv4, error) { + return New(PrependModifiers(modifiers, + WithMessageType(MessageTypeRelease), + WithClientIP(ack.YourIPAddr), + WithHwAddr(ack.ClientHWAddr), + WithBroadcast(false), + WithOptionCopied(ack, OptionServerIdentifier), + )...) +} + +// FromBytes decodes a DHCPv4 packet from a sequence of bytes, and returns an +// error if the packet is not valid. +func FromBytes(q []byte) (*DHCPv4, error) { + var p DHCPv4 + buf := uio.NewBigEndianBuffer(q) + + p.OpCode = OpcodeType(buf.Read8()) + p.HWType = iana.HWType(buf.Read8()) + + hwAddrLen := buf.Read8() + + p.HopCount = buf.Read8() + buf.ReadBytes(p.TransactionID[:]) + p.NumSeconds = buf.Read16() + p.Flags = buf.Read16() + + p.ClientIPAddr = net.IP(buf.CopyN(net.IPv4len)) + p.YourIPAddr = net.IP(buf.CopyN(net.IPv4len)) + p.ServerIPAddr = net.IP(buf.CopyN(net.IPv4len)) + p.GatewayIPAddr = net.IP(buf.CopyN(net.IPv4len)) + + if hwAddrLen > 16 { + hwAddrLen = 16 + } + // Always read 16 bytes, but only use hwaddrlen of them. + p.ClientHWAddr = make(net.HardwareAddr, 16) + buf.ReadBytes(p.ClientHWAddr) + p.ClientHWAddr = p.ClientHWAddr[:hwAddrLen] + + var sname [64]byte + buf.ReadBytes(sname[:]) + length := strings.Index(string(sname[:]), "\x00") + if length == -1 { + length = 64 + } + p.ServerHostName = string(sname[:length]) + + var file [128]byte + buf.ReadBytes(file[:]) + length = strings.Index(string(file[:]), "\x00") + if length == -1 { + length = 128 + } + p.BootFileName = string(file[:length]) + + var cookie [4]byte + buf.ReadBytes(cookie[:]) + + if err := buf.Error(); err != nil { + return nil, err + } + if cookie != magicCookie { + return nil, fmt.Errorf("malformed DHCP packet: got magic cookie %v, want %v", cookie[:], magicCookie[:]) + } + + p.Options = make(Options) + if err := p.Options.fromBytesCheckEnd(buf.Data(), true); err != nil { + return nil, err + } + return &p, nil +} + +// FlagsToString returns a human-readable representation of the flags field. +func (d *DHCPv4) FlagsToString() string { + flags := "" + if d.IsBroadcast() { + flags += "Broadcast" + } else { + flags += "Unicast" + } + if d.Flags&0xfe != 0 { + flags += " (reserved bits not zeroed)" + } + return flags +} + +// IsBroadcast indicates whether the packet is a broadcast packet. +func (d *DHCPv4) IsBroadcast() bool { + return d.Flags&0x8000 == 0x8000 +} + +// SetBroadcast sets the packet to be a broadcast packet. +func (d *DHCPv4) SetBroadcast() { + d.Flags |= 0x8000 +} + +// IsUnicast indicates whether the packet is a unicast packet. +func (d *DHCPv4) IsUnicast() bool { + return d.Flags&0x8000 == 0 +} + +// SetUnicast sets the packet to be a unicast packet. +func (d *DHCPv4) SetUnicast() { + d.Flags &= ^uint16(0x8000) +} + +// GetOneOption returns the option that matches the given option code. +// +// According to RFC 3396, options that are specified more than once are +// concatenated, and hence this should always just return one option. +func (d *DHCPv4) GetOneOption(code OptionCode) []byte { + return d.Options.Get(code) +} + +// DeleteOption deletes an existing option with the given option code. +func (d *DHCPv4) DeleteOption(code OptionCode) { + if d.Options != nil { + d.Options.Del(code) + } +} + +// UpdateOption replaces an existing option with the same option code with the +// given one, adding it if not already present. +func (d *DHCPv4) UpdateOption(opt Option) { + if d.Options == nil { + d.Options = make(Options) + } + d.Options.Update(opt) +} + +// String implements fmt.Stringer. +func (d *DHCPv4) String() string { + return fmt.Sprintf("DHCPv4(xid=%s hwaddr=%s msg_type=%s, your_ip=%s, server_ip=%s)", + d.TransactionID, d.ClientHWAddr, d.MessageType(), d.YourIPAddr, d.ServerIPAddr) +} + +// SummaryWithVendor prints a summary of the packet, interpreting the +// vendor-specific info option using the given parser (can be nil). +func (d *DHCPv4) SummaryWithVendor(vendorDecoder OptionDecoder) string { + ret := fmt.Sprintf( + "DHCPv4 Message\n"+ + " opcode: %s\n"+ + " hwtype: %s\n"+ + " hopcount: %v\n"+ + " transaction ID: %s\n"+ + " num seconds: %v\n"+ + " flags: %v (0x%02x)\n"+ + " client IP: %s\n"+ + " your IP: %s\n"+ + " server IP: %s\n"+ + " gateway IP: %s\n"+ + " client MAC: %s\n"+ + " server hostname: %s\n"+ + " bootfile name: %s\n", + d.OpCode, + d.HWType, + d.HopCount, + d.TransactionID, + d.NumSeconds, + d.FlagsToString(), + d.Flags, + d.ClientIPAddr, + d.YourIPAddr, + d.ServerIPAddr, + d.GatewayIPAddr, + d.ClientHWAddr, + d.ServerHostName, + d.BootFileName, + ) + ret += " options:\n" + ret += d.Options.Summary(vendorDecoder) + return ret +} + +// Summary prints detailed information about the packet. +func (d *DHCPv4) Summary() string { + return d.SummaryWithVendor(nil) +} + +// IsOptionRequested returns true if that option is within the requested +// options of the DHCPv4 message. +func (d *DHCPv4) IsOptionRequested(requested OptionCode) bool { + rq := d.ParameterRequestList() + if rq == nil { + // RFC2131§3.5 + // Not all clients require initialization of all parameters [...] + // Two techniques are used to reduce the number of parameters transmitted from + // the server to the client. [...] Second, in its initial DHCPDISCOVER or + // DHCPREQUEST message, a client may provide the server with a list of specific + // parameters the client is interested in. + // We interpret this to say that all available parameters should be sent if + // the parameter request list is not sent at all. + return true + } + + for _, o := range rq { + if o.Code() == requested.Code() { + return true + } + } + return false +} + +// In case somebody forgets to set an IP, just write 0s as default values. +func writeIP(b *uio.Lexer, ip net.IP) { + var zeros [net.IPv4len]byte + if ip == nil { + b.WriteBytes(zeros[:]) + } else { + // Converting IP to 4 byte format + ip = ip.To4() + b.WriteBytes(ip[:net.IPv4len]) + } +} + +// ToBytes writes the packet to binary. +func (d *DHCPv4) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(make([]byte, 0, minPacketLen)) + buf.Write8(uint8(d.OpCode)) + buf.Write8(uint8(d.HWType)) + + // HwAddrLen + hlen := uint8(len(d.ClientHWAddr)) + buf.Write8(hlen) + buf.Write8(d.HopCount) + buf.WriteBytes(d.TransactionID[:]) + buf.Write16(d.NumSeconds) + buf.Write16(d.Flags) + + writeIP(buf, d.ClientIPAddr) + writeIP(buf, d.YourIPAddr) + writeIP(buf, d.ServerIPAddr) + writeIP(buf, d.GatewayIPAddr) + copy(buf.WriteN(16), d.ClientHWAddr) + + var sname [64]byte + copy(sname[:63], []byte(d.ServerHostName)) + buf.WriteBytes(sname[:]) + + var file [128]byte + copy(file[:127], []byte(d.BootFileName)) + buf.WriteBytes(file[:]) + + // The magic cookie. + buf.WriteBytes(magicCookie[:]) + + // Write all options. + d.Options.Marshal(buf) + + // Finish the options. + buf.Write8(OptionEnd.Code()) + + // DHCP is based on BOOTP, and BOOTP messages have a minimum length of + // 300 bytes per RFC 951. This not stated explicitly, but if you sum up + // all the bytes in the message layout, you'll get 300 bytes. + // + // Some DHCP servers and relay agents care about this BOOTP legacy B.S. + // and "conveniently" drop messages that are less than 300 bytes long. + if buf.Len() < bootpMinLen { + buf.WriteBytes(bytes.Repeat([]byte{OptionPad.Code()}, bootpMinLen-buf.Len())) + } + + return buf.Data() +} + +// GetBroadcastAddress returns the DHCPv4 Broadcast Address value in d. +// +// The broadcast address option is described in RFC 2132, Section 5.3. +func (d *DHCPv4) BroadcastAddress() net.IP { + return GetIP(OptionBroadcastAddress, d.Options) +} + +// RequestedIPAddress returns the DHCPv4 Requested IP Address value in d. +// +// The requested IP address option is described by RFC 2132, Section 9.1. +func (d *DHCPv4) RequestedIPAddress() net.IP { + return GetIP(OptionRequestedIPAddress, d.Options) +} + +// ServerIdentifier returns the DHCPv4 Server Identifier value in d. +// +// The server identifier option is described by RFC 2132, Section 9.7. +func (d *DHCPv4) ServerIdentifier() net.IP { + return GetIP(OptionServerIdentifier, d.Options) +} + +// Router parses the DHCPv4 Router option if present. +// +// The Router option is described by RFC 2132, Section 3.5. +func (d *DHCPv4) Router() []net.IP { + return GetIPs(OptionRouter, d.Options) +} + +// ClasslessStaticRoute parses the DHCPv4 Classless Static Route option if present. +// +// The Classless Static Route option is described by RFC 3442. +func (d *DHCPv4) ClasslessStaticRoute() []*Route { + v := d.Options.Get(OptionClasslessStaticRoute) + if v == nil { + return nil + } + var routes Routes + if err := routes.FromBytes(v); err != nil { + return nil + } + return routes +} + +// NTPServers parses the DHCPv4 NTP Servers option if present. +// +// The NTP servers option is described by RFC 2132, Section 8.3. +func (d *DHCPv4) NTPServers() []net.IP { + return GetIPs(OptionNTPServers, d.Options) +} + +// DNS parses the DHCPv4 Domain Name Server option if present. +// +// The DNS server option is described by RFC 2132, Section 3.8. +func (d *DHCPv4) DNS() []net.IP { + return GetIPs(OptionDomainNameServer, d.Options) +} + +// DomainName parses the DHCPv4 Domain Name option if present. +// +// The Domain Name option is described by RFC 2132, Section 3.17. +func (d *DHCPv4) DomainName() string { + return GetString(OptionDomainName, d.Options) +} + +// HostName parses the DHCPv4 Host Name option if present. +// +// The Host Name option is described by RFC 2132, Section 3.14. +func (d *DHCPv4) HostName() string { + name := GetString(OptionHostName, d.Options) + return strings.TrimRight(name, "\x00") +} + +// RootPath parses the DHCPv4 Root Path option if present. +// +// The Root Path option is described by RFC 2132, Section 3.19. +func (d *DHCPv4) RootPath() string { + return GetString(OptionRootPath, d.Options) +} + +// BootFileNameOption parses the DHCPv4 Bootfile Name option if present. +// +// The Bootfile Name option is described by RFC 2132, Section 9.5. +func (d *DHCPv4) BootFileNameOption() string { + name := GetString(OptionBootfileName, d.Options) + return strings.TrimRight(name, "\x00") +} + +// TFTPServerName parses the DHCPv4 TFTP Server Name option if present. +// +// The TFTP Server Name option is described by RFC 2132, Section 9.4. +func (d *DHCPv4) TFTPServerName() string { + name := GetString(OptionTFTPServerName, d.Options) + return strings.TrimRight(name, "\x00") +} + +// ClassIdentifier parses the DHCPv4 Class Identifier option if present. +// +// The Vendor Class Identifier option is described by RFC 2132, Section 9.13. +func (d *DHCPv4) ClassIdentifier() string { + return GetString(OptionClassIdentifier, d.Options) +} + +// ClientArch returns the Client System Architecture Type option. +func (d *DHCPv4) ClientArch() []iana.Arch { + v := d.Options.Get(OptionClientSystemArchitectureType) + if v == nil { + return nil + } + var archs iana.Archs + if err := archs.FromBytes(v); err != nil { + return nil + } + return archs +} + +// DomainSearch returns the domain search list if present. +// +// The domain search option is described by RFC 3397, Section 2. +func (d *DHCPv4) DomainSearch() *rfc1035label.Labels { + v := d.Options.Get(OptionDNSDomainSearchList) + if v == nil { + return nil + } + labels, err := rfc1035label.FromBytes(v) + if err != nil { + return nil + } + return labels +} + +// IPAddressLeaseTime returns the IP address lease time or the given +// default duration if not present. +// +// The IP address lease time option is described by RFC 2132, Section 9.2. +func (d *DHCPv4) IPAddressLeaseTime(def time.Duration) time.Duration { + v := d.Options.Get(OptionIPAddressLeaseTime) + if v == nil { + return def + } + var dur Duration + if err := dur.FromBytes(v); err != nil { + return def + } + return time.Duration(dur) +} + +// IPAddressRenewalTime returns the IP address renewal time or the given +// default duration if not present. +// +// The IP address renewal time option is described by RFC 2132, Section 9.11. +func (d *DHCPv4) IPAddressRenewalTime(def time.Duration) time.Duration { + v := d.Options.Get(OptionRenewTimeValue) + if v == nil { + return def + } + var dur Duration + if err := dur.FromBytes(v); err != nil { + return def + } + return time.Duration(dur) +} + +// IPAddressRebindingTime returns the IP address rebinding time or the given +// default duration if not present. +// +// The IP address rebinding time option is described by RFC 2132, Section 9.12. +func (d *DHCPv4) IPAddressRebindingTime(def time.Duration) time.Duration { + v := d.Options.Get(OptionRebindingTimeValue) + if v == nil { + return def + } + var dur Duration + if err := dur.FromBytes(v); err != nil { + return def + } + return time.Duration(dur) +} + +// IPv6OnlyPreferred returns the V6ONLY_WAIT duration, and a boolean +// indicating whether this option was present. +// +// The IPv6-Only Preferred option is described by RFC 8925, Section 3.1. +func (d *DHCPv4) IPv6OnlyPreferred() (time.Duration, bool) { + v := d.Options.Get(OptionIPv6OnlyPreferred) + if v == nil { + return 0, false + } + var dur Duration + if err := dur.FromBytes(v); err != nil { + return 0, false + } + return time.Duration(dur), true +} + +// MaxMessageSize returns the DHCP Maximum Message Size if present. +// +// The Maximum DHCP Message Size option is described by RFC 2132, Section 9.10. +func (d *DHCPv4) MaxMessageSize() (uint16, error) { + return GetUint16(OptionMaximumDHCPMessageSize, d.Options) +} + +// AutoConfigure returns the value of the AutoConfigure option, and a +// boolean indicating if it was present. +// +// The AutoConfigure option is described by RFC 2563, Section 2. +func (d *DHCPv4) AutoConfigure() (AutoConfiguration, bool) { + v, err := GetByte(OptionAutoConfigure, d.Options) + return AutoConfiguration(v), err == nil +} + +// MessageType returns the DHCPv4 Message Type option. +func (d *DHCPv4) MessageType() MessageType { + v := d.Options.Get(OptionDHCPMessageType) + if v == nil { + return MessageTypeNone + } + var m MessageType + if err := m.FromBytes(v); err != nil { + return MessageTypeNone + } + return m +} + +// Message returns the DHCPv4 (Error) Message option. +// +// The message options is described in RFC 2132, Section 9.9. +func (d *DHCPv4) Message() string { + return GetString(OptionMessage, d.Options) +} + +// ParameterRequestList returns the DHCPv4 Parameter Request List. +// +// The parameter request list option is described by RFC 2132, Section 9.8. +func (d *DHCPv4) ParameterRequestList() OptionCodeList { + v := d.Options.Get(OptionParameterRequestList) + if v == nil { + return nil + } + var codes OptionCodeList + if err := codes.FromBytes(v); err != nil { + return nil + } + return codes +} + +// RelayAgentInfo returns options embedded by the relay agent. +// +// The relay agent info option is described by RFC 3046. +func (d *DHCPv4) RelayAgentInfo() *RelayOptions { + v := d.Options.Get(OptionRelayAgentInformation) + if v == nil { + return nil + } + var relayOptions RelayOptions + if err := relayOptions.FromBytes(v); err != nil { + return nil + } + return &relayOptions +} + +// SubnetMask returns a subnet mask option contained if present. +// +// The subnet mask option is described by RFC 2132, Section 3.3. +func (d *DHCPv4) SubnetMask() net.IPMask { + v := d.Options.Get(OptionSubnetMask) + if v == nil { + return nil + } + var im IPMask + if err := im.FromBytes(v); err != nil { + return nil + } + return net.IPMask(im) +} + +// UserClass returns the user class if present. +// +// The user class information option is defined by RFC 3004. +func (d *DHCPv4) UserClass() []string { + v := d.Options.Get(OptionUserClassInformation) + if v == nil { + return nil + } + var uc Strings + if err := uc.FromBytes(v); err != nil { + return []string{GetString(OptionUserClassInformation, d.Options)} + } + return uc +} + +// VIVC returns the vendor-identifying vendor class option if present. +func (d *DHCPv4) VIVC() VIVCIdentifiers { + v := d.Options.Get(OptionVendorIdentifyingVendorClass) + if v == nil { + return nil + } + var ids VIVCIdentifiers + if err := ids.FromBytes(v); err != nil { + return nil + } + return ids +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/modifiers.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/modifiers.go new file mode 100644 index 000000000..55863fe0f --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/modifiers.go @@ -0,0 +1,176 @@ +package dhcpv4 + +import ( + "net" + "time" + + "github.com/insomniacslk/dhcp/iana" + "github.com/insomniacslk/dhcp/rfc1035label" +) + +// WithTransactionID sets the Transaction ID for the DHCPv4 packet +func WithTransactionID(xid TransactionID) Modifier { + return func(d *DHCPv4) { + d.TransactionID = xid + } +} + +// WithClientIP sets the Client IP for a DHCPv4 packet. +func WithClientIP(ip net.IP) Modifier { + return func(d *DHCPv4) { + d.ClientIPAddr = ip + } +} + +// WithYourIP sets the Your IP for a DHCPv4 packet. +func WithYourIP(ip net.IP) Modifier { + return func(d *DHCPv4) { + d.YourIPAddr = ip + } +} + +// WithServerIP sets the Server IP for a DHCPv4 packet. +func WithServerIP(ip net.IP) Modifier { + return func(d *DHCPv4) { + d.ServerIPAddr = ip + } +} + +// WithGatewayIP sets the Gateway IP for the DHCPv4 packet. +func WithGatewayIP(ip net.IP) Modifier { + return func(d *DHCPv4) { + d.GatewayIPAddr = ip + } +} + +// WithOptionCopied copies the value of option opt from request. +func WithOptionCopied(request *DHCPv4, opt OptionCode) Modifier { + return func(d *DHCPv4) { + if val := request.Options.Get(opt); val != nil { + d.UpdateOption(OptGeneric(opt, val)) + } + } +} + +// WithReply fills in opcode, hwtype, xid, clienthwaddr, and flags from the given packet. +func WithReply(request *DHCPv4) Modifier { + return func(d *DHCPv4) { + if request.OpCode == OpcodeBootRequest { + d.OpCode = OpcodeBootReply + } else { + d.OpCode = OpcodeBootRequest + } + d.HWType = request.HWType + d.TransactionID = request.TransactionID + d.ClientHWAddr = request.ClientHWAddr + d.Flags = request.Flags + } +} + +// WithHWType sets the Hardware Type for a DHCPv4 packet. +func WithHWType(hwt iana.HWType) Modifier { + return func(d *DHCPv4) { + d.HWType = hwt + } +} + +// WithBroadcast sets the packet to be broadcast or unicast +func WithBroadcast(broadcast bool) Modifier { + return func(d *DHCPv4) { + if broadcast { + d.SetBroadcast() + } else { + d.SetUnicast() + } + } +} + +// WithHwAddr sets the hardware address for a packet +func WithHwAddr(hwaddr net.HardwareAddr) Modifier { + return func(d *DHCPv4) { + d.ClientHWAddr = hwaddr + } +} + +// WithOption appends a DHCPv4 option provided by the user +func WithOption(opt Option) Modifier { + return func(d *DHCPv4) { + d.UpdateOption(opt) + } +} + +// WithoutOption removes the DHCPv4 option with the given code +func WithoutOption(code OptionCode) Modifier { + return func(d *DHCPv4) { + d.DeleteOption(code) + } +} + +// WithUserClass adds a user class option to the packet. +// The rfc parameter allows you to specify if the userclass should be +// rfc compliant or not. More details in issue #113 +func WithUserClass(uc string, rfc bool) Modifier { + // TODO let the user specify multiple user classes + return func(d *DHCPv4) { + if rfc { + d.UpdateOption(OptRFC3004UserClass([]string{uc})) + } else { + d.UpdateOption(OptUserClass(uc)) + } + } +} + +// WithNetboot adds bootfile URL and bootfile param options to a DHCPv4 packet. +func WithNetboot(d *DHCPv4) { + WithRequestedOptions(OptionTFTPServerName, OptionBootfileName)(d) +} + +// WithMessageType adds the DHCPv4 message type m to a packet. +func WithMessageType(m MessageType) Modifier { + return WithOption(OptMessageType(m)) +} + +// WithRequestedOptions adds requested options to the packet. +func WithRequestedOptions(optionCodes ...OptionCode) Modifier { + return func(d *DHCPv4) { + cl := d.ParameterRequestList() + cl.Add(optionCodes...) + d.UpdateOption(OptParameterRequestList(cl...)) + } +} + +// WithRelay adds parameters required for DHCPv4 to be relayed by the relay +// server with given ip +func WithRelay(ip net.IP) Modifier { + return func(d *DHCPv4) { + d.SetUnicast() + d.GatewayIPAddr = ip + d.HopCount++ + } +} + +// WithNetmask adds or updates an OptSubnetMask +func WithNetmask(mask net.IPMask) Modifier { + return WithOption(OptSubnetMask(mask)) +} + +// WithLeaseTime adds or updates an OptIPAddressLeaseTime +func WithLeaseTime(leaseTime uint32) Modifier { + return WithOption(OptIPAddressLeaseTime(time.Duration(leaseTime) * time.Second)) +} + +// WithIPv6OnlyPreferred adds or updates an OptIPv6OnlyPreferred +func WithIPv6OnlyPreferred(v6OnlyWait uint32) Modifier { + return WithOption(OptIPv6OnlyPreferred(time.Duration(v6OnlyWait) * time.Second)) +} + +// WithDomainSearchList adds or updates an OptionDomainSearch +func WithDomainSearchList(searchList ...string) Modifier { + return WithOption(OptDomainSearch(&rfc1035label.Labels{ + Labels: searchList, + })) +} + +func WithGeneric(code OptionCode, value []byte) Modifier { + return WithOption(OptGeneric(code, value)) +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go new file mode 100644 index 000000000..b4e4b567b --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/client.go @@ -0,0 +1,669 @@ +// Copyright 2018 the u-root 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.12 + +// Package nclient4 is a small, minimum-functionality client for DHCPv4. +// +// It only supports the 4-way DHCPv4 Discover-Offer-Request-Ack handshake as +// well as the Request-Ack renewal process. +package nclient4 + +import ( + "bytes" + "context" + "errors" + "fmt" + "log" + "net" + "os" + "sync" + "sync/atomic" + "time" + + "github.com/insomniacslk/dhcp/dhcpv4" +) + +const ( + defaultBufferCap = 5 + + // DefaultTimeout is the default value for read-timeout if option WithTimeout is not set + DefaultTimeout = 5 * time.Second + + // DefaultRetries is amount of retries will be done if no answer was received within read-timeout amount of time + DefaultRetries = 3 + + // MaxMessageSize is the value to be used for DHCP option "MaxMessageSize". + MaxMessageSize = 1500 + + // ClientPort is the port that DHCP clients listen on. + ClientPort = 68 + + // ServerPort is the port that DHCP servers and relay agents listen on. + ServerPort = 67 +) + +var ( + // DefaultServers is the address of all link-local DHCP servers and + // relay agents. + DefaultServers = &net.UDPAddr{ + IP: net.IPv4bcast, + Port: ServerPort, + } +) + +var ( + // ErrNoResponse is returned when no response packet is received. + ErrNoResponse = errors.New("no matching response packet received") + + // ErrNoConn is returned when NewWithConn is called with nil-value as conn. + ErrNoConn = errors.New("conn is nil") + + // ErrNoIfaceHWAddr is returned when NewWithConn is called with nil-value as ifaceHWAddr + ErrNoIfaceHWAddr = errors.New("ifaceHWAddr is nil") +) + +// pendingCh is a channel associated with a pending TransactionID. +type pendingCh struct { + // SendAndRead closes done to indicate that it wishes for no more + // messages for this particular XID. + done <-chan struct{} + + // ch is used by the receive loop to distribute DHCP messages. + ch chan<- *dhcpv4.DHCPv4 +} + +// Logger is a handler which will be used to output logging messages +type Logger interface { + // PrintMessage print _all_ DHCP messages + PrintMessage(prefix string, message *dhcpv4.DHCPv4) + + // Printf is use to print the rest debugging information + Printf(format string, v ...interface{}) +} + +// EmptyLogger prints nothing +type EmptyLogger struct{} + +// Printf is just a dummy function that does nothing +func (e EmptyLogger) Printf(format string, v ...interface{}) {} + +// PrintMessage is just a dummy function that does nothing +func (e EmptyLogger) PrintMessage(prefix string, message *dhcpv4.DHCPv4) {} + +// Printfer is used for actual output of the logger. For example *log.Logger is a Printfer. +type Printfer interface { + // Printf is the function for logging output. Arguments are handled in the manner of fmt.Printf. + Printf(format string, v ...interface{}) +} + +// ShortSummaryLogger is a wrapper for Printfer to implement interface Logger. +// DHCP messages are printed in the short format. +type ShortSummaryLogger struct { + // Printfer is used for actual output of the logger + Printfer +} + +// Printf prints a log message as-is via predefined Printfer +func (s ShortSummaryLogger) Printf(format string, v ...interface{}) { + s.Printfer.Printf(format, v...) +} + +// PrintMessage prints a DHCP message in the short format via predefined Printfer +func (s ShortSummaryLogger) PrintMessage(prefix string, message *dhcpv4.DHCPv4) { + s.Printf("%s: %s", prefix, message) +} + +// DebugLogger is a wrapper for Printfer to implement interface Logger. +// DHCP messages are printed in the long format. +type DebugLogger struct { + // Printfer is used for actual output of the logger + Printfer +} + +// Printf prints a log message as-is via predefined Printfer +func (d DebugLogger) Printf(format string, v ...interface{}) { + d.Printfer.Printf(format, v...) +} + +// PrintMessage prints a DHCP message in the long format via predefined Printfer +func (d DebugLogger) PrintMessage(prefix string, message *dhcpv4.DHCPv4) { + d.Printf("%s: %s", prefix, message.Summary()) +} + +// Client is an IPv4 DHCP client. +type Client struct { + ifaceHWAddr net.HardwareAddr + conn net.PacketConn + timeout time.Duration + retry int + logger Logger + + // bufferCap is the channel capacity for each TransactionID. + bufferCap int + + // serverAddr is the UDP address to send all packets to. + // + // This may be an actual broadcast address, or a unicast address. + serverAddr *net.UDPAddr + + // closed is an atomic bool set to 1 when done is closed. + closed uint32 + + // done is closed to unblock the receive loop. + done chan struct{} + + // wg protects any spawned goroutines, namely the receiveLoop. + wg sync.WaitGroup + + pendingMu sync.Mutex + // pending stores the distribution channels for each pending + // TransactionID. receiveLoop uses this map to determine which channel + // to send a new DHCP message to. + pending map[dhcpv4.TransactionID]*pendingCh +} + +// New returns a client usable with an unconfigured interface. +func New(iface string, opts ...ClientOpt) (*Client, error) { + return new(iface, nil, nil, opts...) +} + +// NewWithConn creates a new DHCP client that sends and receives packets on the +// given interface. +func NewWithConn(conn net.PacketConn, ifaceHWAddr net.HardwareAddr, opts ...ClientOpt) (*Client, error) { + return new(``, conn, ifaceHWAddr, opts...) +} + +func new(iface string, conn net.PacketConn, ifaceHWAddr net.HardwareAddr, opts ...ClientOpt) (*Client, error) { + c := &Client{ + ifaceHWAddr: ifaceHWAddr, + timeout: DefaultTimeout, + retry: DefaultRetries, + serverAddr: DefaultServers, + bufferCap: defaultBufferCap, + conn: conn, + logger: EmptyLogger{}, + + done: make(chan struct{}), + pending: make(map[dhcpv4.TransactionID]*pendingCh), + } + + for _, opt := range opts { + err := opt(c) + if err != nil { + return nil, fmt.Errorf("unable to apply option: %w", err) + } + } + + if c.ifaceHWAddr == nil { + if iface == `` { + return nil, ErrNoIfaceHWAddr + } + + i, err := net.InterfaceByName(iface) + if err != nil { + return nil, fmt.Errorf("unable to get interface information: %w", err) + } + + c.ifaceHWAddr = i.HardwareAddr + } + + if c.conn == nil { + var err error + if iface == `` { + return nil, ErrNoConn + } + c.conn, err = NewRawUDPConn(iface, ClientPort) // broadcast + if err != nil { + return nil, fmt.Errorf("unable to open a broadcasting socket: %w", err) + } + } + c.wg.Add(1) + go c.receiveLoop() + return c, nil +} + +// Close closes the underlying connection. +func (c *Client) Close() error { + // Make sure not to close done twice. + if !atomic.CompareAndSwapUint32(&c.closed, 0, 1) { + return nil + } + + err := c.conn.Close() + + // Closing c.done sets off a chain reaction: + // + // Any SendAndRead unblocks trying to receive more messages, which + // means rem() gets called. + // + // rem() should be unblocking receiveLoop if it is blocked. + // + // receiveLoop should then exit gracefully. + close(c.done) + + // Wait for receiveLoop to stop. + c.wg.Wait() + + return err +} + +func (c *Client) isClosed() bool { + return atomic.LoadUint32(&c.closed) != 0 +} + +func (c *Client) receiveLoop() { + defer c.wg.Done() + for { + // TODO: Clients can send a "max packet size" option in their + // packets, IIRC. Choose a reasonable size and set it. + b := make([]byte, MaxMessageSize) + n, _, err := c.conn.ReadFrom(b) + if err != nil { + if !c.isClosed() { + c.logger.Printf("error reading from UDP connection: %v", err) + } + return + } + + msg, err := dhcpv4.FromBytes(b[:n]) + if err != nil { + // Not a valid DHCP packet; keep listening. + continue + } + + if msg.OpCode != dhcpv4.OpcodeBootReply { + // Not a response message. + continue + } + + // This is a somewhat non-standard check, by the looks + // of RFC 2131. It should work as long as the DHCP + // server is spec-compliant for the HWAddr field. + if c.ifaceHWAddr != nil && !bytes.Equal(c.ifaceHWAddr, msg.ClientHWAddr) { + // Not for us. + continue + } + + c.pendingMu.Lock() + p, ok := c.pending[msg.TransactionID] + if ok { + select { + case <-p.done: + close(p.ch) + delete(c.pending, msg.TransactionID) + + // This send may block. + case p.ch <- msg: + } + } + c.pendingMu.Unlock() + } +} + +// ClientOpt is a function that configures the Client. +type ClientOpt func(c *Client) error + +// WithTimeout configures the retransmission timeout. +// +// Default is 5 seconds. +func WithTimeout(d time.Duration) ClientOpt { + return func(c *Client) (err error) { + c.timeout = d + return + } +} + +// WithSummaryLogger logs one-line DHCPv4 message summaries when sent & received. +func WithSummaryLogger() ClientOpt { + return func(c *Client) (err error) { + c.logger = ShortSummaryLogger{ + Printfer: log.New(os.Stderr, "[dhcpv4] ", log.LstdFlags), + } + return + } +} + +// WithDebugLogger logs multi-line full DHCPv4 messages when sent & received. +func WithDebugLogger() ClientOpt { + return func(c *Client) (err error) { + c.logger = DebugLogger{ + Printfer: log.New(os.Stderr, "[dhcpv4] ", log.LstdFlags), + } + return + } +} + +// WithLogger set the logger (see interface Logger). +func WithLogger(newLogger Logger) ClientOpt { + return func(c *Client) (err error) { + c.logger = newLogger + return + } +} + +// WithUnicast forces client to send messages as unicast frames. +// By default client sends messages as broadcast frames even if server address is defined. +// +// srcAddr is both: +// * The source address of outgoing frames. +// * The address to be listened for incoming frames. +func WithUnicast(srcAddr *net.UDPAddr) ClientOpt { + return func(c *Client) (err error) { + if srcAddr == nil { + srcAddr = &net.UDPAddr{Port: ClientPort} + } + c.conn, err = net.ListenUDP("udp4", srcAddr) + if err != nil { + err = fmt.Errorf("unable to start listening UDP port: %w", err) + } + return + } +} + +// WithHWAddr tells to the Client to receive messages destinated to selected +// hardware address +func WithHWAddr(hwAddr net.HardwareAddr) ClientOpt { + return func(c *Client) (err error) { + c.ifaceHWAddr = hwAddr + return + } +} + +func withBufferCap(n int) ClientOpt { + return func(c *Client) (err error) { + c.bufferCap = n + return + } +} + +// WithRetry configures the number of retransmissions to attempt. +// +// Default is 3. +func WithRetry(r int) ClientOpt { + return func(c *Client) (err error) { + c.retry = r + return + } +} + +// WithServerAddr configures the address to send messages to. +func WithServerAddr(n *net.UDPAddr) ClientOpt { + return func(c *Client) (err error) { + c.serverAddr = n + return + } +} + +// Matcher matches DHCP packets. +type Matcher func(*dhcpv4.DHCPv4) bool + +// IsMessageType returns a matcher that checks for the message types. +func IsMessageType(t dhcpv4.MessageType, tt ...dhcpv4.MessageType) Matcher { + return func(p *dhcpv4.DHCPv4) bool { + if p.MessageType() == t { + return true + } + for _, mt := range tt { + if p.MessageType() == mt { + return true + } + } + return false + } +} + +// IsCorrectServer returns a matcher that checks for the correct ServerAddress. +func IsCorrectServer(s net.IP) Matcher { + return func(p *dhcpv4.DHCPv4) bool { + return p.ServerIdentifier().Equal(s) + } +} + +// IsAll returns a matcher that checks for all given matchers to be true. +func IsAll(ms ...Matcher) Matcher { + return func(p *dhcpv4.DHCPv4) bool { + for _, m := range ms { + if !m(p) { + return false + } + } + return true + } +} + +// RemoteAddr is the default DHCP server address this client sends messages to. +func (c *Client) RemoteAddr() *net.UDPAddr { + // Make a copy so the caller cannot modify the address once the client + // is running. + cop := *c.serverAddr + return &cop +} + +// InterfaceAddr returns the MAC address of the client's interface. +func (c *Client) InterfaceAddr() net.HardwareAddr { + b := make(net.HardwareAddr, len(c.ifaceHWAddr)) + copy(b, c.ifaceHWAddr) + return b +} + +// DiscoverOffer sends a DHCPDiscover message and returns the first valid offer +// received. +func (c *Client) DiscoverOffer(ctx context.Context, modifiers ...dhcpv4.Modifier) (offer *dhcpv4.DHCPv4, err error) { + // RFC 2131, Section 4.4.1, Table 5 details what a DISCOVER packet should + // contain. + discover, err := dhcpv4.NewDiscovery(c.ifaceHWAddr, dhcpv4.PrependModifiers(modifiers, + dhcpv4.WithOption(dhcpv4.OptMaxMessageSize(MaxMessageSize)))...) + if err != nil { + return nil, fmt.Errorf("unable to create a discovery request: %w", err) + } + + offer, err = c.SendAndRead(ctx, c.serverAddr, discover, IsMessageType(dhcpv4.MessageTypeOffer)) + if err != nil { + return nil, fmt.Errorf("got an error while the discovery request: %w", err) + } + return offer, nil +} + +// Request completes the 4-way Discover-Offer-Request-Ack handshake. +// +// Note that modifiers will be applied *both* to Discover and Request packets. +func (c *Client) Request(ctx context.Context, modifiers ...dhcpv4.Modifier) (lease *Lease, err error) { + offer, err := c.DiscoverOffer(ctx, modifiers...) + if err != nil { + err = fmt.Errorf("unable to receive an offer: %w", err) + return + } + return c.RequestFromOffer(ctx, offer, modifiers...) +} + +// Inform sends an INFORM request using the given local IP. +// Returns the ACK response from the server on success. +func (c *Client) Inform(ctx context.Context, localIP net.IP, modifiers ...dhcpv4.Modifier) (*dhcpv4.DHCPv4, error) { + request, err := dhcpv4.NewInform(c.ifaceHWAddr, localIP, modifiers...) + if err != nil { + return nil, err + } + + // DHCP clients must not fill in the server identifier in an INFORM request as per RFC 2131 Section 4.4.1 Table 5, + // however, they may still unicast the request to the target server if the address is known (c.serverAddr), as per + // Section 4.4.3. The server must then respond with an ACK, as per Section 4.3.5. + response, err := c.SendAndRead(ctx, c.serverAddr, request, IsMessageType(dhcpv4.MessageTypeAck)) + if err != nil { + return nil, fmt.Errorf("got an error while processing the request: %w", err) + } + + return response, nil +} + +// ErrNak is returned if a DHCP server rejected our Request. +type ErrNak struct { + Offer *dhcpv4.DHCPv4 + Nak *dhcpv4.DHCPv4 +} + +// Error implements error.Error. +func (e *ErrNak) Error() string { + if msg := e.Nak.Message(); len(msg) > 0 { + return fmt.Sprintf("server rejected request with Nak (msg: %s)", msg) + } + return "server rejected request with Nak" +} + +// RequestFromOffer sends a Request message and waits for an response. +// It assumes the SELECTING state by default, see Section 4.3.2 in RFC 2131 for more details. +func (c *Client) RequestFromOffer(ctx context.Context, offer *dhcpv4.DHCPv4, modifiers ...dhcpv4.Modifier) (*Lease, error) { + // TODO(chrisko): should this be unicast to the server? + request, err := dhcpv4.NewRequestFromOffer(offer, dhcpv4.PrependModifiers(modifiers, + dhcpv4.WithOption(dhcpv4.OptMaxMessageSize(MaxMessageSize)))...) + if err != nil { + return nil, fmt.Errorf("unable to create a request: %w", err) + } + + // Servers are supposed to only respond to Requests containing their server identifier, + // but sometimes non-compliant servers respond anyway. + // Clients are not required to validate this field, but servers are required to + // include the server identifier in their Offer per RFC 2131 Section 4.3.1 Table 3. + response, err := c.SendAndRead(ctx, c.serverAddr, request, IsAll( + IsCorrectServer(offer.ServerIdentifier()), + IsMessageType(dhcpv4.MessageTypeAck, dhcpv4.MessageTypeNak))) + if err != nil { + return nil, fmt.Errorf("got an error while processing the request: %w", err) + } + if response.MessageType() == dhcpv4.MessageTypeNak { + return nil, &ErrNak{ + Offer: offer, + Nak: response, + } + } + lease := &Lease{} + lease.ACK = response + lease.Offer = offer + lease.CreationTime = time.Now() + return lease, nil +} + +// ErrTransactionIDInUse is returned if there were an attempt to send a message +// with the same TransactionID as we are already waiting an answer for. +type ErrTransactionIDInUse struct { + // TransactionID is the transaction ID of the message which the error is related to. + TransactionID dhcpv4.TransactionID +} + +// Error is just the method to comply interface "error". +func (err *ErrTransactionIDInUse) Error() string { + return fmt.Sprintf("transaction ID %s already in use", err.TransactionID) +} + +// send sends p to destination and returns a response channel. +// +// Responses will be matched by transaction ID and ClientHWAddr. +// +// The returned lambda function must be called after all desired responses have +// been received in order to return the Transaction ID to the usable pool. +func (c *Client) send(dest *net.UDPAddr, msg *dhcpv4.DHCPv4) (resp <-chan *dhcpv4.DHCPv4, cancel func(), err error) { + c.pendingMu.Lock() + if _, ok := c.pending[msg.TransactionID]; ok { + c.pendingMu.Unlock() + return nil, nil, &ErrTransactionIDInUse{msg.TransactionID} + } + + ch := make(chan *dhcpv4.DHCPv4, c.bufferCap) + done := make(chan struct{}) + c.pending[msg.TransactionID] = &pendingCh{done: done, ch: ch} + c.pendingMu.Unlock() + + cancel = func() { + // Why can't we just close ch here? + // + // Because receiveLoop may potentially be blocked trying to + // send on ch. We gotta unblock it first, and then we can take + // the lock and remove the XID from the pending transaction + // map. + close(done) + + c.pendingMu.Lock() + if p, ok := c.pending[msg.TransactionID]; ok { + close(p.ch) + delete(c.pending, msg.TransactionID) + } + c.pendingMu.Unlock() + } + + if _, err := c.conn.WriteTo(msg.ToBytes(), dest); err != nil { + cancel() + return nil, nil, fmt.Errorf("error writing packet to connection: %w", err) + } + return ch, cancel, nil +} + +// This error should never be visible to users. +// It is used only to increase the timeout in retryFn. +var errDeadlineExceeded = errors.New("INTERNAL ERROR: deadline exceeded") + +// SendAndRead sends a packet p to a destination dest and waits for the first +// response matching `match` as well as its Transaction ID and ClientHWAddr. +// +// If match is nil, the first packet matching the Transaction ID and +// ClientHWAddr is returned. +func (c *Client) SendAndRead(ctx context.Context, dest *net.UDPAddr, p *dhcpv4.DHCPv4, match Matcher) (*dhcpv4.DHCPv4, error) { + var response *dhcpv4.DHCPv4 + err := c.retryFn(func(timeout time.Duration) error { + ch, rem, err := c.send(dest, p) + if err != nil { + return err + } + c.logger.PrintMessage("sent message", p) + defer rem() + + for { + select { + case <-c.done: + return ErrNoResponse + + case <-time.After(timeout): + return errDeadlineExceeded + + case <-ctx.Done(): + return ctx.Err() + + case packet := <-ch: + if match == nil || match(packet) { + c.logger.PrintMessage("received message", packet) + response = packet + return nil + } + } + } + }) + if err == errDeadlineExceeded { + return nil, ErrNoResponse + } + if err != nil { + return nil, err + } + return response, nil +} + +func (c *Client) retryFn(fn func(timeout time.Duration) error) error { + timeout := c.timeout + + // Each retry takes the amount of timeout at worst. + for i := 0; i < c.retry || c.retry < 0; i++ { // TODO: why is this called "retry" if this is "tries" ("retries"+1)? + switch err := fn(timeout); err { + case nil: + // Got it! + return nil + + case errDeadlineExceeded: + // Double timeout, then retry. + timeout *= 2 + + default: + return err + } + } + + return errDeadlineExceeded +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/conn_unix.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/conn_unix.go new file mode 100644 index 000000000..f3e48c66e --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/conn_unix.go @@ -0,0 +1,154 @@ +// Copyright 2018 the u-root Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.12 && (darwin || freebsd || linux || netbsd || openbsd || dragonfly) +// +build go1.12 +// +build darwin freebsd linux netbsd openbsd dragonfly + +package nclient4 + +import ( + "errors" + "io" + "net" + + "github.com/mdlayher/packet" + "github.com/u-root/uio/uio" + "golang.org/x/sys/unix" +) + +var ( + // BroadcastMac is the broadcast MAC address. + // + // Any UDP packet sent to this address is broadcast on the subnet. + BroadcastMac = net.HardwareAddr([]byte{255, 255, 255, 255, 255, 255}) +) + +var ( + // ErrUDPAddrIsRequired is an error used when a passed argument is not of type "*net.UDPAddr". + ErrUDPAddrIsRequired = errors.New("must supply UDPAddr") +) + +// NewRawUDPConn returns a UDP connection bound to the interface and port +// given based on a raw packet socket. All packets are broadcasted. +// +// The interface can be completely unconfigured. +func NewRawUDPConn(iface string, port int) (net.PacketConn, error) { + ifc, err := net.InterfaceByName(iface) + if err != nil { + return nil, err + } + rawConn, err := packet.Listen(ifc, packet.Datagram, unix.ETH_P_IP, nil) + if err != nil { + return nil, err + } + return NewBroadcastUDPConn(rawConn, &net.UDPAddr{Port: port}), nil +} + +// BroadcastRawUDPConn uses a raw socket to send UDP packets to the broadcast +// MAC address. +type BroadcastRawUDPConn struct { + // PacketConn is a raw DGRAM socket. + net.PacketConn + + // boundAddr is the address this RawUDPConn is "bound" to. + // + // Calls to ReadFrom will only return packets destined to this address. + boundAddr *net.UDPAddr +} + +// NewBroadcastUDPConn returns a PacketConn that marshals and unmarshals UDP +// packets, sending them to the broadcast MAC at on rawPacketConn. +// +// Calls to ReadFrom will only return packets destined to boundAddr. +func NewBroadcastUDPConn(rawPacketConn net.PacketConn, boundAddr *net.UDPAddr) net.PacketConn { + return &BroadcastRawUDPConn{ + PacketConn: rawPacketConn, + boundAddr: boundAddr, + } +} + +func udpMatch(addr *net.UDPAddr, bound *net.UDPAddr) bool { + if bound == nil { + return true + } + if bound.IP != nil && !bound.IP.Equal(addr.IP) { + return false + } + return bound.Port == addr.Port +} + +// ReadFrom implements net.PacketConn.ReadFrom. +// +// ReadFrom reads raw IP packets and will try to match them against +// upc.boundAddr. Any matching packets are returned via the given buffer. +func (upc *BroadcastRawUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { + ipHdrMaxLen := ipv4MaximumHeaderSize + udpHdrLen := udpMinimumSize + + for { + pkt := make([]byte, ipHdrMaxLen+udpHdrLen+len(b)) + n, _, err := upc.PacketConn.ReadFrom(pkt) + if err != nil { + return 0, nil, err + } + if n == 0 { + return 0, nil, io.EOF + } + pkt = pkt[:n] + buf := uio.NewBigEndianBuffer(pkt) + + ipHdr := ipv4(buf.Data()) + + if !ipHdr.isValid(n) { + continue + } + + ipHdr = ipv4(buf.Consume(int(ipHdr.headerLength()))) + + if ipHdr.transportProtocol() != udpProtocolNumber { + continue + } + + if !buf.Has(udpHdrLen) { + continue + } + + udpHdr := udp(buf.Consume(udpHdrLen)) + + addr := &net.UDPAddr{ + IP: ipHdr.destinationAddress(), + Port: int(udpHdr.destinationPort()), + } + if !udpMatch(addr, upc.boundAddr) { + continue + } + srcAddr := &net.UDPAddr{ + IP: ipHdr.sourceAddress(), + Port: int(udpHdr.sourcePort()), + } + // Extra padding after end of IP packet should be ignored, + // if not dhcp option parsing will fail. + dhcpLen := int(ipHdr.payloadLength()) - udpHdrLen + return copy(b, buf.Consume(dhcpLen)), srcAddr, nil + } +} + +// WriteTo implements net.PacketConn.WriteTo and broadcasts all packets at the +// raw socket level. +// +// WriteTo wraps the given packet in the appropriate UDP and IP header before +// sending it on the packet conn. +func (upc *BroadcastRawUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) { + udpAddr, ok := addr.(*net.UDPAddr) + if !ok { + return 0, ErrUDPAddrIsRequired + } + + // Using the boundAddr is not quite right here, but it works. + pkt := udp4pkt(b, udpAddr, upc.boundAddr) + + // Broadcasting is not always right, but hell, what the ARP do I know. + return upc.PacketConn.WriteTo(pkt, &packet.Addr{HardwareAddr: BroadcastMac}) +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/ipv4.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/ipv4.go new file mode 100644 index 000000000..f2bfb6517 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/ipv4.go @@ -0,0 +1,360 @@ +// Copyright 2018 Google LLC +// +// 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. +// +// This file contains code taken from gVisor. + +//go:build go1.12 +// +build go1.12 + +package nclient4 + +import ( + "encoding/binary" + "net" + + "github.com/u-root/uio/uio" +) + +const ( + versIHL = 0 + tos = 1 + totalLen = 2 + id = 4 + flagsFO = 6 + ttl = 8 + protocol = 9 + checksumOff = 10 + srcAddr = 12 + dstAddr = 16 +) + +// transportProtocolNumber is the number of a transport protocol. +type transportProtocolNumber uint32 + +// ipv4Fields contains the fields of an IPv4 packet. It is used to describe the +// fields of a packet that needs to be encoded. +type ipv4Fields struct { + // IHL is the "internet header length" field of an IPv4 packet. + IHL uint8 + + // TOS is the "type of service" field of an IPv4 packet. + TOS uint8 + + // TotalLength is the "total length" field of an IPv4 packet. + TotalLength uint16 + + // ID is the "identification" field of an IPv4 packet. + ID uint16 + + // Flags is the "flags" field of an IPv4 packet. + Flags uint8 + + // FragmentOffset is the "fragment offset" field of an IPv4 packet. + FragmentOffset uint16 + + // TTL is the "time to live" field of an IPv4 packet. + TTL uint8 + + // Protocol is the "protocol" field of an IPv4 packet. + Protocol uint8 + + // checksum is the "checksum" field of an IPv4 packet. + checksum uint16 + + // SrcAddr is the "source ip address" of an IPv4 packet. + SrcAddr net.IP + + // DstAddr is the "destination ip address" of an IPv4 packet. + DstAddr net.IP +} + +// ipv4 represents an ipv4 header stored in a byte array. +// Most of the methods of IPv4 access to the underlying slice without +// checking the boundaries and could panic because of 'index out of range'. +// Always call IsValid() to validate an instance of IPv4 before using other methods. +type ipv4 []byte + +const ( + // ipv4MinimumSize is the minimum size of a valid IPv4 packet. + ipv4MinimumSize = 20 + + // ipv4MaximumHeaderSize is the maximum size of an IPv4 header. Given + // that there are only 4 bits to represents the header length in 32-bit + // units, the header cannot exceed 15*4 = 60 bytes. + ipv4MaximumHeaderSize = 60 + + // ipv4AddressSize is the size, in bytes, of an IPv4 address. + ipv4AddressSize = 4 + + // IPv4Version is the version of the IPv4 protocol. + ipv4Version = 4 +) + +// ipVersion returns the version of IP used in the given packet. It returns -1 +// if the packet is not large enough to contain the version field. +func ipVersion(b []byte) int { + // Length must be at least offset+length of version field. + if len(b) < versIHL+1 { + return -1 + } + return int(b[versIHL] >> ipVersionShift) +} + +const ( + ipVersionShift = 4 +) + +// headerLength returns the value of the "header length" field of the ipv4 +// header. +func (b ipv4) headerLength() uint8 { + return (b[versIHL] & 0xf) * 4 +} + +// protocol returns the value of the protocol field of the ipv4 header. +func (b ipv4) protocol() uint8 { + return b[protocol] +} + +// sourceAddress returns the "source address" field of the ipv4 header. +func (b ipv4) sourceAddress() net.IP { + return net.IP(b[srcAddr : srcAddr+ipv4AddressSize]) +} + +// destinationAddress returns the "destination address" field of the ipv4 +// header. +func (b ipv4) destinationAddress() net.IP { + return net.IP(b[dstAddr : dstAddr+ipv4AddressSize]) +} + +// transportProtocol implements Network.transportProtocol. +func (b ipv4) transportProtocol() transportProtocolNumber { + return transportProtocolNumber(b.protocol()) +} + +// payloadLength returns the length of the payload portion of the ipv4 packet. +func (b ipv4) payloadLength() uint16 { + return b.totalLength() - uint16(b.headerLength()) +} + +// totalLength returns the "total length" field of the ipv4 header. +func (b ipv4) totalLength() uint16 { + return binary.BigEndian.Uint16(b[totalLen:]) +} + +// setTotalLength sets the "total length" field of the ipv4 header. +func (b ipv4) setTotalLength(totalLength uint16) { + binary.BigEndian.PutUint16(b[totalLen:], totalLength) +} + +// setChecksum sets the checksum field of the ipv4 header. +func (b ipv4) setChecksum(v uint16) { + binary.BigEndian.PutUint16(b[checksumOff:], v) +} + +// setFlagsFragmentOffset sets the "flags" and "fragment offset" fields of the +// ipv4 header. +func (b ipv4) setFlagsFragmentOffset(flags uint8, offset uint16) { + v := (uint16(flags) << 13) | (offset >> 3) + binary.BigEndian.PutUint16(b[flagsFO:], v) +} + +// calculateChecksum calculates the checksum of the ipv4 header. +func (b ipv4) calculateChecksum() uint16 { + return checksum(b[:b.headerLength()], 0) +} + +// encode encodes all the fields of the ipv4 header. +func (b ipv4) encode(i *ipv4Fields) { + b[versIHL] = (4 << 4) | ((i.IHL / 4) & 0xf) + b[tos] = i.TOS + b.setTotalLength(i.TotalLength) + binary.BigEndian.PutUint16(b[id:], i.ID) + b.setFlagsFragmentOffset(i.Flags, i.FragmentOffset) + b[ttl] = i.TTL + b[protocol] = i.Protocol + b.setChecksum(i.checksum) + copy(b[srcAddr:srcAddr+ipv4AddressSize], i.SrcAddr) + copy(b[dstAddr:dstAddr+ipv4AddressSize], i.DstAddr) +} + +// isValid performs basic validation on the packet. +func (b ipv4) isValid(pktSize int) bool { + if len(b) < ipv4MinimumSize { + return false + } + + hlen := int(b.headerLength()) + tlen := int(b.totalLength()) + if hlen < ipv4MinimumSize || hlen > tlen || tlen > pktSize { + return false + } + + if ipVersion(b) != ipv4Version { + return false + } + + return true +} + +const ( + udpSrcPort = 0 + udpDstPort = 2 + udpLength = 4 + udpchecksum = 6 +) + +// udpFields contains the fields of a udp packet. It is used to describe the +// fields of a packet that needs to be encoded. +type udpFields struct { + // SrcPort is the "source port" field of a udp packet. + SrcPort uint16 + + // DstPort is the "destination port" field of a UDP packet. + DstPort uint16 + + // Length is the "length" field of a UDP packet. + Length uint16 + + // checksum is the "checksum" field of a UDP packet. + checksum uint16 +} + +// udp represents a udp header stored in a byte array. +type udp []byte + +const ( + // udpMinimumSize is the minimum size of a valid udp packet. + udpMinimumSize = 8 + + // udpProtocolNumber is udp's transport protocol number. + udpProtocolNumber transportProtocolNumber = 17 +) + +// sourcePort returns the "source port" field of the udp header. +func (b udp) sourcePort() uint16 { + return binary.BigEndian.Uint16(b[udpSrcPort:]) +} + +// DestinationPort returns the "destination port" field of the udp header. +func (b udp) destinationPort() uint16 { + return binary.BigEndian.Uint16(b[udpDstPort:]) +} + +// Length returns the "length" field of the udp header. +func (b udp) length() uint16 { + return binary.BigEndian.Uint16(b[udpLength:]) +} + +// setChecksum sets the "checksum" field of the udp header. +func (b udp) setChecksum(checksum uint16) { + binary.BigEndian.PutUint16(b[udpchecksum:], checksum) +} + +// calculateChecksum calculates the checksum of the udp packet, given the total +// length of the packet and the checksum of the network-layer pseudo-header +// (excluding the total length) and the checksum of the payload. +func (b udp) calculateChecksum(partialchecksum uint16, totalLen uint16) uint16 { + // Add the length portion of the checksum to the pseudo-checksum. + tmp := make([]byte, 2) + binary.BigEndian.PutUint16(tmp, totalLen) + xsum := checksum(tmp, partialchecksum) + + // Calculate the rest of the checksum. + return checksum(b[:udpMinimumSize], xsum) +} + +// encode encodes all the fields of the udp header. +func (b udp) encode(u *udpFields) { + binary.BigEndian.PutUint16(b[udpSrcPort:], u.SrcPort) + binary.BigEndian.PutUint16(b[udpDstPort:], u.DstPort) + binary.BigEndian.PutUint16(b[udpLength:], u.Length) + binary.BigEndian.PutUint16(b[udpchecksum:], u.checksum) +} + +func calculateChecksum(buf []byte, initial uint32) uint16 { + v := initial + + l := len(buf) + if l&1 != 0 { + l-- + v += uint32(buf[l]) << 8 + } + + for i := 0; i < l; i += 2 { + v += (uint32(buf[i]) << 8) + uint32(buf[i+1]) + } + + return checksumCombine(uint16(v), uint16(v>>16)) +} + +// checksum calculates the checksum (as defined in RFC 1071) of the bytes in the +// given byte array. +// +// The initial checksum must have been computed on an even number of bytes. +func checksum(buf []byte, initial uint16) uint16 { + return calculateChecksum(buf, uint32(initial)) +} + +// checksumCombine combines the two uint16 to form their checksum. This is done +// by adding them and the carry. +// +// Note that checksum a must have been computed on an even number of bytes. +func checksumCombine(a, b uint16) uint16 { + v := uint32(a) + uint32(b) + return uint16(v + v>>16) +} + +// pseudoHeaderchecksum calculates the pseudo-header checksum for the +// given destination protocol and network address, ignoring the length +// field. pseudo-headers are needed by transport layers when calculating +// their own checksum. +func pseudoHeaderchecksum(protocol transportProtocolNumber, srcAddr net.IP, dstAddr net.IP) uint16 { + xsum := checksum([]byte(srcAddr), 0) + xsum = checksum([]byte(dstAddr), xsum) + return checksum([]byte{0, uint8(protocol)}, xsum) +} + +func udp4pkt(packet []byte, dest *net.UDPAddr, src *net.UDPAddr) []byte { + ipLen := ipv4MinimumSize + udpLen := udpMinimumSize + + h := make([]byte, 0, ipLen+udpLen+len(packet)) + hdr := uio.NewBigEndianBuffer(h) + + ipv4fields := &ipv4Fields{ + IHL: ipv4MinimumSize, + TotalLength: uint16(ipLen + udpLen + len(packet)), + TTL: 64, // Per RFC 1700's recommendation for IP time to live + Protocol: uint8(udpProtocolNumber), + SrcAddr: src.IP.To4(), + DstAddr: dest.IP.To4(), + } + ipv4hdr := ipv4(hdr.WriteN(ipLen)) + ipv4hdr.encode(ipv4fields) + ipv4hdr.setChecksum(^ipv4hdr.calculateChecksum()) + + udphdr := udp(hdr.WriteN(udpLen)) + udphdr.encode(&udpFields{ + SrcPort: uint16(src.Port), + DstPort: uint16(dest.Port), + Length: uint16(udpLen + len(packet)), + }) + + xsum := checksum(packet, pseudoHeaderchecksum( + ipv4hdr.transportProtocol(), ipv4fields.SrcAddr, ipv4fields.DstAddr)) + udphdr.setChecksum(^udphdr.calculateChecksum(xsum, udphdr.length())) + + hdr.WriteBytes(packet) + return hdr.Data() +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/lease.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/lease.go new file mode 100644 index 000000000..8b1d9e6be --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/nclient4/lease.go @@ -0,0 +1,79 @@ +// This is lease support for nclient4 + +package nclient4 + +import ( + "context" + "fmt" + "net" + "time" + + "github.com/insomniacslk/dhcp/dhcpv4" +) + +// Lease contains a DHCPv4 lease after DORA. +// note: Lease doesn't include binding interface name +type Lease struct { + Offer *dhcpv4.DHCPv4 + ACK *dhcpv4.DHCPv4 + CreationTime time.Time +} + +// Release send DHCPv4 release messsage to server, based on specified lease. +// release is sent as unicast per RFC2131, section 4.4.4. +// Note: some DHCP server requries of using assigned IP address as source IP, +// use nclient4.WithUnicast to create client for such case. +func (c *Client) Release(lease *Lease, modifiers ...dhcpv4.Modifier) error { + if lease == nil { + return fmt.Errorf("lease is nil") + } + req, err := dhcpv4.NewReleaseFromACK(lease.ACK, modifiers...) + if err != nil { + return fmt.Errorf("fail to create release request,%w", err) + } + _, err = c.conn.WriteTo(req.ToBytes(), &net.UDPAddr{IP: lease.ACK.Options.Get(dhcpv4.OptionServerIdentifier), Port: ServerPort}) + if err == nil { + c.logger.PrintMessage("sent message:", req) + } + return err +} + +// Renew sends a DHCPv4 request to the server to renew the given lease. The renewal information is +// sourced from the initial offer in the lease, and the ACK of the lease is updated to the ACK of +// the latest renewal. This avoids issues with DHCP servers that omit information needed to build a +// completely new lease from their renewal ACK (such as the Windows DHCP Server). +func (c *Client) Renew(ctx context.Context, lease *Lease, modifiers ...dhcpv4.Modifier) (*Lease, error) { + if lease == nil { + return nil, fmt.Errorf("lease is nil") + } + + request, err := dhcpv4.NewRenewFromAck(lease.ACK, dhcpv4.PrependModifiers(modifiers, + dhcpv4.WithOption(dhcpv4.OptMaxMessageSize(MaxMessageSize)))...) + if err != nil { + return nil, fmt.Errorf("unable to create a request: %w", err) + } + + // Servers are supposed to only respond to Requests containing their server identifier, + // but sometimes non-compliant servers respond anyway. + // Clients are not required to validate this field, but servers are required to + // include the server identifier in their Offer per RFC 2131 Section 4.3.1 Table 3. + response, err := c.SendAndRead(ctx, c.serverAddr, request, IsAll( + IsCorrectServer(lease.Offer.ServerIdentifier()), + IsMessageType(dhcpv4.MessageTypeAck, dhcpv4.MessageTypeNak))) + if err != nil { + return nil, fmt.Errorf("got an error while processing the request: %w", err) + } + if response.MessageType() == dhcpv4.MessageTypeNak { + return nil, &ErrNak{ + Offer: lease.Offer, + Nak: response, + } + } + + // Return a new lease with the latest ACK and updated creation time + return &Lease{ + Offer: lease.Offer, + ACK: response, + CreationTime: time.Now(), + }, nil +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_autoconfigure.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_autoconfigure.go new file mode 100644 index 000000000..e2237bfc4 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_autoconfigure.go @@ -0,0 +1,61 @@ +package dhcpv4 + +import ( + "fmt" +) + +// AutoConfiguration implements encoding and decoding functions for a +// byte enumeration as used in RFC 2563, Section 2. +type AutoConfiguration byte + +const ( + DoNotAutoConfigure AutoConfiguration = 0 + AutoConfigure AutoConfiguration = 1 +) + +var autoConfigureToString = map[AutoConfiguration]string{ + DoNotAutoConfigure: "DoNotAutoConfigure", + AutoConfigure: "AutoConfigure", +} + +// ToBytes returns a serialized stream of bytes for this option. +func (o AutoConfiguration) ToBytes() []byte { + return []byte{byte(o)} +} + +// String returns a human-readable string for this option. +func (o AutoConfiguration) String() string { + s := autoConfigureToString[o] + if s != "" { + return s + } + return fmt.Sprintf("UNKNOWN (%d)", byte(o)) +} + +// FromBytes parses a a single byte into AutoConfiguration +func (o *AutoConfiguration) FromBytes(data []byte) error { + if len(data) == 1 { + *o = AutoConfiguration(data[0]) + return nil + } + return fmt.Errorf("Invalid buffer length (%d)", len(data)) +} + +// GetByte parses any single-byte option +func GetByte(code OptionCode, o Options) (byte, error) { + data := o.Get(code) + if data == nil { + return 0, fmt.Errorf("option not present") + } + if len(data) != 1 { + return 0, fmt.Errorf("Invalid buffer length (%d)", len(data)) + } + return data[0], nil +} + +// OptAutoConfigure returns a new AutoConfigure option. +// +// The AutoConfigure option is described by RFC 2563, Section 2. +func OptAutoConfigure(autoconf AutoConfiguration) Option { + return Option{Code: OptionAutoConfigure, Value: autoconf} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_duration.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_duration.go new file mode 100644 index 000000000..80be32d84 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_duration.go @@ -0,0 +1,56 @@ +package dhcpv4 + +import ( + "math" + "time" + + "github.com/u-root/uio/uio" +) + +// MaxLeaseTime is the maximum lease time that can be encoded. +var MaxLeaseTime = math.MaxUint32 * time.Second + +// Duration implements the IP address lease time option described by RFC 2132, +// Section 9.2. +type Duration time.Duration + +// FromBytes parses a duration from a byte stream according to RFC 2132, Section 9.2. +func (d *Duration) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + *d = Duration(time.Duration(buf.Read32()) * time.Second) + return buf.FinError() +} + +// ToBytes returns a serialized stream of bytes for this option. +func (d Duration) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(nil) + buf.Write32(uint32(time.Duration(d) / time.Second)) + return buf.Data() +} + +// String returns a human-readable string for this option. +func (d Duration) String() string { + return time.Duration(d).String() +} + +// OptIPAddressLeaseTime returns a new IP address lease time option. +// +// The IP address lease time option is described by RFC 2132, Section 9.2. +func OptIPAddressLeaseTime(d time.Duration) Option { + return Option{Code: OptionIPAddressLeaseTime, Value: Duration(d)} +} + +// The IP address renew time option as described by RFC 2132, Section 9.11. +func OptRenewTimeValue(d time.Duration) Option { + return Option{Code: OptionRenewTimeValue, Value: Duration(d)} +} + +// The IP address rebinding time option as described by RFC 2132, Section 9.12. +func OptRebindingTimeValue(d time.Duration) Option { + return Option{Code: OptionRebindingTimeValue, Value: Duration(d)} +} + +// The IPv6-Only Preferred option is described by RFC 8925, Section 3.1 +func OptIPv6OnlyPreferred(d time.Duration) Option { + return Option{Code: OptionIPv6OnlyPreferred, Value: Duration(d)} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_generic.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_generic.go new file mode 100644 index 000000000..a54cdeb73 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_generic.go @@ -0,0 +1,27 @@ +package dhcpv4 + +import ( + "fmt" +) + +// OptionGeneric is an option that only contains the option code and associated +// data. Every option that does not have a specific implementation will fall +// back to this option. +type OptionGeneric struct { + Data []byte +} + +// ToBytes returns a serialized generic option as a slice of bytes. +func (o OptionGeneric) ToBytes() []byte { + return o.Data +} + +// String returns a human-readable representation of a generic option. +func (o OptionGeneric) String() string { + return fmt.Sprintf("%v", o.Data) +} + +// OptGeneric returns a generic option. +func OptGeneric(code OptionCode, value []byte) Option { + return Option{Code: code, Value: OptionGeneric{value}} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ip.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ip.go new file mode 100644 index 000000000..c573631dc --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ip.go @@ -0,0 +1,62 @@ +package dhcpv4 + +import ( + "net" + + "github.com/u-root/uio/uio" +) + +// IP implements DHCPv4 IP option marshaling and unmarshaling as described by +// RFC 2132, Sections 5.3, 9.1, 9.7, and others. +type IP net.IP + +// FromBytes parses an IP from data in binary form. +func (i *IP) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + *i = IP(buf.CopyN(net.IPv4len)) + return buf.FinError() +} + +// ToBytes returns a serialized stream of bytes for this option. +func (i IP) ToBytes() []byte { + return []byte(net.IP(i).To4()) +} + +// String returns a human-readable IP. +func (i IP) String() string { + return net.IP(i).String() +} + +// GetIP returns code out of o parsed as an IP. +func GetIP(code OptionCode, o Options) net.IP { + v := o.Get(code) + if v == nil { + return nil + } + var ip IP + if err := ip.FromBytes(v); err != nil { + return nil + } + return net.IP(ip) +} + +// OptBroadcastAddress returns a new DHCPv4 Broadcast Address option. +// +// The broadcast address option is described in RFC 2132, Section 5.3. +func OptBroadcastAddress(ip net.IP) Option { + return Option{Code: OptionBroadcastAddress, Value: IP(ip)} +} + +// OptRequestedIPAddress returns a new DHCPv4 Requested IP Address option. +// +// The requested IP address option is described by RFC 2132, Section 9.1. +func OptRequestedIPAddress(ip net.IP) Option { + return Option{Code: OptionRequestedIPAddress, Value: IP(ip)} +} + +// OptServerIdentifier returns a new DHCPv4 Server Identifier option. +// +// The server identifier option is described by RFC 2132, Section 9.7. +func OptServerIdentifier(ip net.IP) Option { + return Option{Code: OptionServerIdentifier, Value: IP(ip)} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ips.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ips.go new file mode 100644 index 000000000..e0ee4cd0b --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_ips.go @@ -0,0 +1,103 @@ +package dhcpv4 + +import ( + "fmt" + "net" + "strings" + + "github.com/u-root/uio/uio" +) + +// IPs are IPv4 addresses from a DHCP packet as used and specified by options +// in RFC 2132, Sections 3.5 through 3.13, 8.2, 8.3, 8.5, 8.6, 8.9, and 8.10. +// +// IPs implements the OptionValue type. +type IPs []net.IP + +// FromBytes parses an IPv4 address from a DHCP packet as used and specified by +// options in RFC 2132, Sections 3.5 through 3.13, 8.2, 8.3, 8.5, 8.6, 8.9, and +// 8.10. +func (i *IPs) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + if buf.Len() == 0 { + return fmt.Errorf("IP DHCP options must always list at least one IP") + } + + *i = make(IPs, 0, buf.Len()/net.IPv4len) + for buf.Has(net.IPv4len) { + *i = append(*i, net.IP(buf.CopyN(net.IPv4len))) + } + return buf.FinError() +} + +// ToBytes marshals IPv4 addresses to a DHCP packet as specified by RFC 2132, +// Section 3.5 et al. +func (i IPs) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(nil) + for _, ip := range i { + buf.WriteBytes(ip.To4()) + } + return buf.Data() +} + +// String returns a human-readable representation of a list of IPs. +func (i IPs) String() string { + s := make([]string, 0, len(i)) + for _, ip := range i { + s = append(s, ip.String()) + } + return strings.Join(s, ", ") +} + +// GetIPs parses a list of IPs from code in o. +func GetIPs(code OptionCode, o Options) []net.IP { + v := o.Get(code) + if v == nil { + return nil + } + var ips IPs + if err := ips.FromBytes(v); err != nil { + return nil + } + return []net.IP(ips) +} + +// OptRouter returns a new DHCPv4 Router option. +// +// The Router option is described by RFC 2132, Section 3.5. +func OptRouter(routers ...net.IP) Option { + return Option{ + Code: OptionRouter, + Value: IPs(routers), + } +} + +// WithRouter updates a packet with the DHCPv4 Router option. +func WithRouter(routers ...net.IP) Modifier { + return WithOption(OptRouter(routers...)) +} + +// OptNTPServers returns a new DHCPv4 NTP Server option. +// +// The NTP servers option is described by RFC 2132, Section 8.3. +func OptNTPServers(ntpServers ...net.IP) Option { + return Option{ + Code: OptionNTPServers, + Value: IPs(ntpServers), + } +} + +// OptDNS returns a new DHCPv4 Domain Name Server option. +// +// The DNS server option is described by RFC 2132, Section 3.8. +func OptDNS(servers ...net.IP) Option { + return Option{ + Code: OptionDomainNameServer, + Value: IPs(servers), + } +} + +// WithDNS modifies a packet with the DHCPv4 Domain Name Server option. +func WithDNS(servers ...net.IP) Modifier { + return WithOption(OptDNS(servers...)) +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_maximum_dhcp_message_size.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_maximum_dhcp_message_size.go new file mode 100644 index 000000000..f28302383 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_maximum_dhcp_message_size.go @@ -0,0 +1,50 @@ +package dhcpv4 + +import ( + "fmt" + + "github.com/u-root/uio/uio" +) + +// Uint16 implements encoding and decoding functions for a uint16 as used in +// RFC 2132, Section 9.10. +type Uint16 uint16 + +// ToBytes returns a serialized stream of bytes for this option. +func (o Uint16) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(nil) + buf.Write16(uint16(o)) + return buf.Data() +} + +// String returns a human-readable string for this option. +func (o Uint16) String() string { + return fmt.Sprintf("%d", uint16(o)) +} + +// FromBytes decodes data into o as per RFC 2132, Section 9.10. +func (o *Uint16) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + *o = Uint16(buf.Read16()) + return buf.FinError() +} + +// GetUint16 parses a uint16 from code in o. +func GetUint16(code OptionCode, o Options) (uint16, error) { + v := o.Get(code) + if v == nil { + return 0, fmt.Errorf("option not present") + } + var u Uint16 + if err := u.FromBytes(v); err != nil { + return 0, err + } + return uint16(u), nil +} + +// OptMaxMessageSize returns a new DHCP Maximum Message Size option. +// +// The Maximum DHCP Message Size option is described by RFC 2132, Section 9.10. +func OptMaxMessageSize(size uint16) Option { + return Option{Code: OptionMaximumDHCPMessageSize, Value: Uint16(size)} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_message_type.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_message_type.go new file mode 100644 index 000000000..1f4c14f20 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_message_type.go @@ -0,0 +1,6 @@ +package dhcpv4 + +// OptMessageType returns a new DHCPv4 Message Type option. +func OptMessageType(m MessageType) Option { + return Option{Code: OptionDHCPMessageType, Value: m} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_misc.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_misc.go new file mode 100644 index 000000000..e91b34d80 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_misc.go @@ -0,0 +1,23 @@ +package dhcpv4 + +import ( + "github.com/insomniacslk/dhcp/iana" + "github.com/insomniacslk/dhcp/rfc1035label" +) + +// OptDomainSearch returns a new domain search option. +// +// The domain search option is described by RFC 3397, Section 2. +func OptDomainSearch(labels *rfc1035label.Labels) Option { + return Option{Code: OptionDNSDomainSearchList, Value: labels} +} + +// OptClientArch returns a new Client System Architecture Type option. +func OptClientArch(archs ...iana.Arch) Option { + return Option{Code: OptionClientSystemArchitectureType, Value: iana.Archs(archs)} +} + +// OptClientIdentifier returns a new Client Identifier option. +func OptClientIdentifier(ident []byte) Option { + return OptGeneric(OptionClientIdentifier, ident) +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_parameter_request_list.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_parameter_request_list.go new file mode 100644 index 000000000..72b447cb8 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_parameter_request_list.go @@ -0,0 +1,72 @@ +package dhcpv4 + +import ( + "sort" + "strings" + + "github.com/u-root/uio/uio" +) + +// OptionCodeList is a list of DHCP option codes. +type OptionCodeList []OptionCode + +// Has returns whether c is in the list. +func (ol OptionCodeList) Has(c OptionCode) bool { + for _, code := range ol { + if code == c { + return true + } + } + return false +} + +// Add adds option codes in cs to ol. +func (ol *OptionCodeList) Add(cs ...OptionCode) { + for _, c := range cs { + if !ol.Has(c) { + *ol = append(*ol, c) + } + } +} + +func (ol OptionCodeList) sort() { + sort.Slice(ol, func(i, j int) bool { return ol[i].Code() < ol[j].Code() }) +} + +// String returns a human-readable string for the option names. +func (ol OptionCodeList) String() string { + var names []string + ol.sort() + for _, code := range ol { + names = append(names, code.String()) + } + return strings.Join(names, ", ") +} + +// ToBytes returns a serialized stream of bytes for this option as defined by +// RFC 2132, Section 9.8. +func (ol OptionCodeList) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(nil) + for _, req := range ol { + buf.Write8(req.Code()) + } + return buf.Data() +} + +// FromBytes parses a byte stream for this option as described by RFC 2132, +// Section 9.8. +func (ol *OptionCodeList) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + *ol = make(OptionCodeList, 0, buf.Len()) + for buf.Has(1) { + *ol = append(*ol, optionCode(buf.Read8())) + } + return buf.FinError() +} + +// OptParameterRequestList returns a new DHCPv4 Parameter Request List. +// +// The parameter request list option is described by RFC 2132, Section 9.8. +func OptParameterRequestList(codes ...OptionCode) Option { + return Option{Code: OptionParameterRequestList, Value: OptionCodeList(codes)} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_relay_agent_information.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_relay_agent_information.go new file mode 100644 index 000000000..451402f56 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_relay_agent_information.go @@ -0,0 +1,100 @@ +package dhcpv4 + +import ( + "fmt" +) + +// RelayOptions is like Options, but stringifies using the Relay Agent Specific +// option space. +type RelayOptions struct { + Options +} + +var relayHumanizer = OptionHumanizer{ + ValueHumanizer: func(code OptionCode, data []byte) fmt.Stringer { + var d OptionDecoder + switch code { + case LinkSelectionSubOption, ServerIdentifierOverrideSubOption: + d = &IPs{} + } + if d != nil && d.FromBytes(data) == nil { + return d + } + return raiSubOptionValue{data} + }, + CodeHumanizer: func(c uint8) OptionCode { + return raiSubOptionCode(c) + }, +} + +// String prints the contained options using Relay Agent-specific option code parsing. +func (r RelayOptions) String() string { + return "\n" + r.Options.ToString(relayHumanizer) +} + +// FromBytes parses relay agent options from data. +func (r *RelayOptions) FromBytes(data []byte) error { + r.Options = make(Options) + return r.Options.FromBytes(data) +} + +// OptRelayAgentInfo returns a new DHCP Relay Agent Info option. +// +// The relay agent info option is described by RFC 3046. +func OptRelayAgentInfo(o ...Option) Option { + return Option{Code: OptionRelayAgentInformation, Value: RelayOptions{OptionsFromList(o...)}} +} + +type raiSubOptionValue struct { + val []byte +} + +func (rv raiSubOptionValue) String() string { + return fmt.Sprintf("%q (%v)", string(rv.val), rv.val) +} + +type raiSubOptionCode uint8 + +func (o raiSubOptionCode) Code() uint8 { + return uint8(o) +} + +func (o raiSubOptionCode) String() string { + if s, ok := raiSubOptionCodeToString[o]; ok { + return s + } + return fmt.Sprintf("unknown (%d)", o) +} + +// Option 82 Relay Agention Information Sub Options +const ( + AgentCircuitIDSubOption raiSubOptionCode = 1 // RFC 3046 + AgentRemoteIDSubOption raiSubOptionCode = 2 // RFC 3046 + DOCSISDeviceClassSubOption raiSubOptionCode = 4 // RFC 3256 + LinkSelectionSubOption raiSubOptionCode = 5 // RFC 3527 + SubscriberIDSubOption raiSubOptionCode = 6 // RFC 3993 + RADIUSAttributesSubOption raiSubOptionCode = 7 // RFC 4014 + AuthenticationSubOption raiSubOptionCode = 8 // RFC 4030 + VendorSpecificInformationSubOption raiSubOptionCode = 9 // RFC 4243 + RelayAgentFlagsSubOption raiSubOptionCode = 10 // RFC 5010 + ServerIdentifierOverrideSubOption raiSubOptionCode = 11 // RFC 5107 + RelaySourcePortSubOption raiSubOptionCode = 19 // RFC 8357 + VirtualSubnetSelectionSubOption raiSubOptionCode = 151 // RFC 6607 + VirtualSubnetSelectionControlSubOption raiSubOptionCode = 152 // RFC 6607 +) + +var raiSubOptionCodeToString = map[raiSubOptionCode]string{ + AgentCircuitIDSubOption: "Agent Circuit ID Sub-option", + AgentRemoteIDSubOption: "Agent Remote ID Sub-option", + DOCSISDeviceClassSubOption: "DOCSIS Device Class Sub-option", + LinkSelectionSubOption: "Link Selection Sub-option", + SubscriberIDSubOption: "Subscriber ID Sub-option", + RADIUSAttributesSubOption: "RADIUS Attributes Sub-option", + AuthenticationSubOption: "Authentication Sub-option", + VendorSpecificInformationSubOption: "Vendor Specific Sub-option", + RelayAgentFlagsSubOption: "Relay Agent Flags Sub-option", + ServerIdentifierOverrideSubOption: "Server Identifier Override Sub-option", + RelaySourcePortSubOption: "Relay Source Port Sub-option", + VirtualSubnetSelectionSubOption: "Virtual Subnet Selection Sub-option", + VirtualSubnetSelectionControlSubOption: "Virtual Subnet Selection Control Sub-option", +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_routes.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_routes.go new file mode 100644 index 000000000..8516629cf --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_routes.go @@ -0,0 +1,104 @@ +package dhcpv4 + +import ( + "fmt" + "net" + "strings" + + "github.com/u-root/uio/uio" +) + +// Route is a classless static route as per RFC 3442. +type Route struct { + // Dest is the destination network. + Dest *net.IPNet + + // Router is the router to use for the given destination network. + Router net.IP +} + +// Marshal implements uio.Marshaler. +// +// Format described in RFC 3442: +// +// +// +// +func (r Route) Marshal(buf *uio.Lexer) { + ones, _ := r.Dest.Mask.Size() + buf.Write8(uint8(ones)) + + // Only write the non-zero octets. + dstLen := (ones + 7) / 8 + buf.WriteBytes(r.Dest.IP.To4()[:dstLen]) + + buf.WriteBytes(r.Router.To4()) +} + +// Unmarshal implements uio.Unmarshaler. +func (r *Route) Unmarshal(buf *uio.Lexer) error { + maskSize := buf.Read8() + if maskSize > 32 { + return fmt.Errorf("invalid mask length %d in route option", maskSize) + } + r.Dest = &net.IPNet{ + IP: make([]byte, net.IPv4len), + Mask: net.CIDRMask(int(maskSize), 32), + } + + dstLen := (maskSize + 7) / 8 + buf.ReadBytes(r.Dest.IP[:dstLen]) + + r.Router = buf.CopyN(net.IPv4len) + return buf.Error() +} + +// String prints the destination network and router IP. +func (r *Route) String() string { + return fmt.Sprintf("route to %s via %s", r.Dest, r.Router) +} + +// Routes is a collection of network routes. +type Routes []*Route + +// FromBytes parses routes from a set of bytes as described by RFC 3442. +func (r *Routes) FromBytes(p []byte) error { + buf := uio.NewBigEndianBuffer(p) + for buf.Has(1) { + var route Route + if err := route.Unmarshal(buf); err != nil { + return err + } + *r = append(*r, &route) + } + return buf.FinError() +} + +// ToBytes marshals a set of routes as described by RFC 3442. +func (r Routes) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(nil) + for _, route := range r { + route.Marshal(buf) + } + return buf.Data() +} + +// String prints all routes. +func (r Routes) String() string { + s := make([]string, 0, len(r)) + for _, route := range r { + s = append(s, route.String()) + } + return strings.Join(s, "; ") +} + +// OptClasslessStaticRoute returns a new DHCPv4 Classless Static Route +// option. +// +// The Classless Static Route option is described by RFC 3442. +func OptClasslessStaticRoute(routes ...*Route) Option { + return Option{ + Code: OptionClasslessStaticRoute, + Value: Routes(routes), + } +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_string.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_string.go new file mode 100644 index 000000000..eb0cc2b0d --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_string.go @@ -0,0 +1,84 @@ +package dhcpv4 + +// String represents an option encapsulating a string in IPv4 DHCP. +// +// This representation is shared by multiple options specified by RFC 2132, +// Sections 3.14, 3.16, 3.17, 3.19, and 3.20. +type String string + +// ToBytes returns a serialized stream of bytes for this option. +func (o String) ToBytes() []byte { + return []byte(o) +} + +// String returns a human-readable string. +func (o String) String() string { + return string(o) +} + +// FromBytes parses a serialized stream of bytes into o. +func (o *String) FromBytes(data []byte) error { + *o = String(string(data)) + return nil +} + +// GetString parses an RFC 2132 string from o[code]. +func GetString(code OptionCode, o Options) string { + v := o.Get(code) + if v == nil { + return "" + } + return string(v) +} + +// OptDomainName returns a new DHCPv4 Domain Name option. +// +// The Domain Name option is described by RFC 2132, Section 3.17. +func OptDomainName(name string) Option { + return Option{Code: OptionDomainName, Value: String(name)} +} + +// OptHostName returns a new DHCPv4 Host Name option. +// +// The Host Name option is described by RFC 2132, Section 3.14. +func OptHostName(name string) Option { + return Option{Code: OptionHostName, Value: String(name)} +} + +// OptRootPath returns a new DHCPv4 Root Path option. +// +// The Root Path option is described by RFC 2132, Section 3.19. +func OptRootPath(name string) Option { + return Option{Code: OptionRootPath, Value: String(name)} +} + +// OptBootFileName returns a new DHCPv4 Boot File Name option. +// +// The Bootfile Name option is described by RFC 2132, Section 9.5. +func OptBootFileName(name string) Option { + return Option{Code: OptionBootfileName, Value: String(name)} +} + +// OptTFTPServerName returns a new DHCPv4 TFTP Server Name option. +// +// The TFTP Server Name option is described by RFC 2132, Section 9.4. +func OptTFTPServerName(name string) Option { + return Option{Code: OptionTFTPServerName, Value: String(name)} +} + +// OptClassIdentifier returns a new DHCPv4 Class Identifier option. +// +// The Vendor Class Identifier option is described by RFC 2132, Section 9.13. +func OptClassIdentifier(name string) Option { + return Option{Code: OptionClassIdentifier, Value: String(name)} +} + +// OptUserClass returns a new DHCPv4 User Class option. +func OptUserClass(name string) Option { + return Option{Code: OptionUserClassInformation, Value: String(name)} +} + +// OptMessage returns a new DHCPv4 (Error) Message option. +func OptMessage(msg string) Option { + return Option{Code: OptionMessage, Value: String(msg)} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_strings.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_strings.go new file mode 100644 index 000000000..a29baa504 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_strings.go @@ -0,0 +1,55 @@ +package dhcpv4 + +import ( + "fmt" + "strings" + + "github.com/u-root/uio/uio" +) + +// Strings represents an option encapsulating a list of strings in IPv4 DHCP as +// specified in RFC 3004 +// +// Strings implements the OptionValue type. +type Strings []string + +// FromBytes parses Strings from a DHCP packet as specified by RFC 3004. +func (o *Strings) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + if buf.Len() == 0 { + return fmt.Errorf("Strings DHCP option must always list at least one String") + } + + *o = make(Strings, 0) + for buf.Has(1) { + ucLen := buf.Read8() + if ucLen == 0 { + return fmt.Errorf("DHCP Strings must have length greater than 0") + } + *o = append(*o, string(buf.CopyN(int(ucLen)))) + } + return buf.FinError() +} + +// ToBytes marshals Strings to a DHCP packet as specified by RFC 3004. +func (o Strings) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(nil) + for _, uc := range o { + buf.Write8(uint8(len(uc))) + buf.WriteBytes([]byte(uc)) + } + return buf.Data() +} + +// String returns a human-readable representation of a list of Strings. +func (o Strings) String() string { + return strings.Join(o, ", ") +} + +// OptRFC3004UserClass returns a new user class option according to RFC 3004. +func OptRFC3004UserClass(v []string) Option { + return Option{ + Code: OptionUserClassInformation, + Value: Strings(v), + } +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_subnet_mask.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_subnet_mask.go new file mode 100644 index 000000000..a2f9f62f3 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_subnet_mask.go @@ -0,0 +1,40 @@ +package dhcpv4 + +import ( + "net" + + "github.com/u-root/uio/uio" +) + +// IPMask represents an option encapsulating the subnet mask. +// +// This option implements the subnet mask option in RFC 2132, Section 3.3. +type IPMask net.IPMask + +// ToBytes returns a serialized stream of bytes for this option. +func (im IPMask) ToBytes() []byte { + if len(im) > net.IPv4len { + return im[:net.IPv4len] + } + return im +} + +// String returns a human-readable string. +func (im IPMask) String() string { + return net.IPMask(im).String() +} + +// FromBytes parses im from data per RFC 2132. +func (im *IPMask) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + *im = IPMask(buf.CopyN(net.IPv4len)) + return buf.FinError() +} + +// OptSubnetMask returns a new DHCPv4 SubnetMask option per RFC 2132, Section 3.3. +func OptSubnetMask(mask net.IPMask) Option { + return Option{ + Code: OptionSubnetMask, + Value: IPMask(mask), + } +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_vivc.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_vivc.go new file mode 100644 index 000000000..3900bf024 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/option_vivc.go @@ -0,0 +1,65 @@ +package dhcpv4 + +import ( + "bytes" + "fmt" + + "github.com/insomniacslk/dhcp/iana" + "github.com/u-root/uio/uio" +) + +// VIVCIdentifier implements the vendor-identifying vendor class option +// described by RFC 3925. +type VIVCIdentifier struct { + // EntID is the enterprise ID. + EntID iana.EnterpriseID + Data []byte +} + +// OptVIVC returns a new vendor-identifying vendor class option. +// +// The option is described by RFC 3925. +func OptVIVC(identifiers ...VIVCIdentifier) Option { + return Option{ + Code: OptionVendorIdentifyingVendorClass, + Value: VIVCIdentifiers(identifiers), + } +} + +// VIVCIdentifiers implements encoding and decoding methods for a DHCP option +// described in RFC 3925. +type VIVCIdentifiers []VIVCIdentifier + +// FromBytes parses data into ids per RFC 3925. +func (ids *VIVCIdentifiers) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + for buf.Has(5) { + entID := iana.EnterpriseID(buf.Read32()) + idLen := int(buf.Read8()) + *ids = append(*ids, VIVCIdentifier{EntID: entID, Data: buf.CopyN(idLen)}) + } + return buf.FinError() +} + +// ToBytes returns a serialized stream of bytes for this option. +func (ids VIVCIdentifiers) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(nil) + for _, id := range ids { + buf.Write32(uint32(id.EntID)) + buf.Write8(uint8(len(id.Data))) + buf.WriteBytes(id.Data) + } + return buf.Data() +} + +// String returns a human-readable string for this option. +func (ids VIVCIdentifiers) String() string { + if len(ids) == 0 { + return "" + } + buf := bytes.Buffer{} + for _, id := range ids { + fmt.Fprintf(&buf, " %d:'%s',", id.EntID, id.Data) + } + return buf.String()[1 : buf.Len()-1] +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/options.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/options.go new file mode 100644 index 000000000..186682917 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/options.go @@ -0,0 +1,380 @@ +package dhcpv4 + +import ( + "errors" + "fmt" + "io" + "math" + "sort" + "strings" + + "github.com/insomniacslk/dhcp/iana" + "github.com/insomniacslk/dhcp/rfc1035label" + "github.com/u-root/uio/uio" +) + +var ( + // ErrShortByteStream is an error that is thrown any time a short byte stream is + // detected during option parsing. + ErrShortByteStream = errors.New("short byte stream") + + // ErrZeroLengthByteStream is an error that is thrown any time a zero-length + // byte stream is encountered. + ErrZeroLengthByteStream = errors.New("zero-length byte stream") +) + +// OptionValue is an interface that all DHCP v4 options adhere to. +type OptionValue interface { + ToBytes() []byte + String() string +} + +// Option is a DHCPv4 option and consists of a 1-byte option code and a value +// stream of bytes. +// +// The value is to be interpreted based on the option code. +type Option struct { + Code OptionCode + Value OptionValue +} + +// String returns a human-readable version of this option. +func (o Option) String() string { + v := o.Value.String() + if strings.Contains(v, "\n") { + return fmt.Sprintf("%s:\n%s", o.Code, v) + } + return fmt.Sprintf("%s: %s", o.Code, v) +} + +// Options is a collection of options. +type Options map[uint8][]byte + +// OptionsFromList adds all given options to an options map. +func OptionsFromList(o ...Option) Options { + opts := make(Options) + for _, opt := range o { + opts.Update(opt) + } + return opts +} + +// Get will attempt to get all options that match a DHCPv4 option +// from its OptionCode. If the option was not found it will return an +// empty list. +// +// According to RFC 3396, options that are specified more than once are +// concatenated, and hence this should always just return one option. This +// currently returns a list to be API compatible. +func (o Options) Get(code OptionCode) []byte { + return o[code.Code()] +} + +// Has checks whether o has the given opcode. +func (o Options) Has(opcode OptionCode) bool { + _, ok := o[opcode.Code()] + return ok +} + +// Del deletes the option matching the option code. +func (o Options) Del(opcode OptionCode) { + delete(o, opcode.Code()) +} + +// Update updates the existing options with the passed option, adding it +// at the end if not present already +func (o Options) Update(option Option) { + o[option.Code.Code()] = option.Value.ToBytes() +} + +// ToBytes makes Options usable as an OptionValue as well. +// +// Used in the case of vendor-specific and relay agent options. +func (o Options) ToBytes() []byte { + return uio.ToBigEndian(o) +} + +// FromBytes parses a sequence of bytes until the end and builds a list of +// options from it. +// +// The sequence should not contain the DHCP magic cookie. +// +// Returns an error if any invalid option or length is found. +func (o Options) FromBytes(data []byte) error { + return o.fromBytesCheckEnd(data, false) +} + +const ( + optPad = 0 + optAgentInfo = 82 + optEnd = 255 +) + +// FromBytesCheckEnd parses Options from byte sequences using the +// parsing function that is passed in as a paremeter +func (o Options) fromBytesCheckEnd(data []byte, checkEndOption bool) error { + if len(data) == 0 { + return nil + } + buf := uio.NewBigEndianBuffer(data) + + var end bool + for buf.Len() >= 1 { + // 1 byte: option code + // 1 byte: option length n + // n bytes: data + code := buf.Read8() + + if code == optPad { + continue + } else if code == optEnd { + end = true + break + } + length := int(buf.Read8()) + + // N bytes: option data + data := buf.Consume(length) + if data == nil { + return fmt.Errorf("error collecting options: %v", buf.Error()) + } + data = data[:length:length] + + // RFC 2131, Section 4.1 "Options may appear only once, [...]. + // The client concatenates the values of multiple instances of + // the same option into a single parameter list for + // configuration." + // + // See also RFC 3396 for concatenation order and options longer + // than 255 bytes. + o[code] = append(o[code], data...) + } + + // If we never read the End option, the sender of this packet screwed + // up. + if !end && checkEndOption { + return io.ErrUnexpectedEOF + } + + return nil +} + +// sortedKeys returns an ordered slice of option keys from the Options map, for +// use in serializing options to binary. +func (o Options) sortedKeys() []int { + // Send all values for a given key + var codes []int + var hasOptAgentInfo, hasOptEnd bool + for k := range o { + // RFC 3046 section 2.1 states that option 82 SHALL come last (ignoring End). + if k == optAgentInfo { + hasOptAgentInfo = true + continue + } + if k == optEnd { + hasOptEnd = true + continue + } + codes = append(codes, int(k)) + } + + sort.Ints(codes) + + if hasOptAgentInfo { + codes = append(codes, optAgentInfo) + } + if hasOptEnd { + codes = append(codes, optEnd) + } + return codes +} + +// Marshal writes options binary representations to b. +func (o Options) Marshal(b *uio.Lexer) { + for _, c := range o.sortedKeys() { + code := uint8(c) + // Even if the End option is in there, don't marshal it until + // the end. + // Don't write padding either, since the options are sorted + // it would always be written first which isn't useful + if code == optEnd || code == optPad { + continue + } + + data := o[code] + + // Ensure even 0-length options are written out + if len(data) == 0 { + b.Write8(code) + b.Write8(0) + continue + } + // RFC 3396: If more than 256 bytes of data are given, the + // option is simply listed multiple times. + for len(data) > 0 { + // 1 byte: option code + b.Write8(code) + + n := len(data) + if n > math.MaxUint8 { + n = math.MaxUint8 + } + + // 1 byte: option length + b.Write8(uint8(n)) + + // N bytes: option data + b.WriteBytes(data[:n]) + data = data[n:] + } + } +} + +// String prints options using DHCP-specified option codes. +func (o Options) String() string { + return o.ToString(dhcpHumanizer) +} + +// Summary prints options in human-readable values. +// +// Summary uses vendorParser to interpret the OptionVendorSpecificInformation option. +func (o Options) Summary(vendorDecoder OptionDecoder) string { + return o.ToString(OptionHumanizer{ + ValueHumanizer: parserFor(vendorDecoder), + CodeHumanizer: func(c uint8) OptionCode { + return optionCode(c) + }, + }) +} + +// OptionParser gives a human-legible interpretation of data for the given option code. +type OptionParser func(code OptionCode, data []byte) fmt.Stringer + +// OptionHumanizer is used to interpret a set of Options for their option code +// name and values. +// +// There should be separate OptionHumanizers for each Option "space": DHCP, +// BSDP, Relay Agent Info, and others. +type OptionHumanizer struct { + ValueHumanizer OptionParser + CodeHumanizer func(code uint8) OptionCode +} + +// Stringify returns a human-readable interpretation of the option code and its +// associated data. +func (oh OptionHumanizer) Stringify(code uint8, data []byte) string { + c := oh.CodeHumanizer(code) + val := oh.ValueHumanizer(c, data) + return fmt.Sprintf("%s: %s", c, val) +} + +// dhcpHumanizer humanizes the set of DHCP option codes. +var dhcpHumanizer = OptionHumanizer{ + ValueHumanizer: parseOption, + CodeHumanizer: func(c uint8) OptionCode { + return optionCode(c) + }, +} + +// ToString uses parse to parse options into human-readable values. +func (o Options) ToString(humanizer OptionHumanizer) string { + var ret string + for _, c := range o.sortedKeys() { + code := uint8(c) + v := o[code] + optString := humanizer.Stringify(code, v) + // If this option has sub structures, offset them accordingly. + if strings.Contains(optString, "\n") { + optString = strings.Replace(optString, "\n ", "\n ", -1) + } + ret += fmt.Sprintf(" %v\n", optString) + } + return ret +} + +func parseOption(code OptionCode, data []byte) fmt.Stringer { + return parserFor(nil)(code, data) +} + +func parserFor(vendorParser OptionDecoder) OptionParser { + return func(code OptionCode, data []byte) fmt.Stringer { + return getOption(code, data, vendorParser) + } +} + +// OptionDecoder can decode a byte stream into a human-readable option. +type OptionDecoder interface { + fmt.Stringer + FromBytes([]byte) error +} + +func getOption(code OptionCode, data []byte, vendorDecoder OptionDecoder) fmt.Stringer { + var d OptionDecoder + switch code { + case OptionRouter, OptionDomainNameServer, OptionNTPServers, OptionServerIdentifier: + d = &IPs{} + + case OptionBroadcastAddress, OptionRequestedIPAddress: + d = &IP{} + + case OptionClientSystemArchitectureType: + d = &iana.Archs{} + + case OptionSubnetMask: + d = &IPMask{} + + case OptionDHCPMessageType: + var mt MessageType + d = &mt + + case OptionParameterRequestList: + d = &OptionCodeList{} + + case OptionHostName, OptionDomainName, OptionRootPath, + OptionClassIdentifier, OptionTFTPServerName, OptionBootfileName, + OptionMessage, OptionReferenceToTZDatabase: + var s String + d = &s + + case OptionRelayAgentInformation: + d = &RelayOptions{} + + case OptionDNSDomainSearchList: + d = &rfc1035label.Labels{} + + case OptionIPAddressLeaseTime, OptionRenewTimeValue, + OptionRebindingTimeValue, OptionIPv6OnlyPreferred, OptionArpCacheTimeout, + OptionTimeOffset: + var dur Duration + d = &dur + + case OptionMaximumDHCPMessageSize: + var u Uint16 + d = &u + + case OptionUserClassInformation: + var s Strings + d = &s + if s.FromBytes(data) != nil { + var s String + d = &s + } + + case OptionAutoConfigure: + var a AutoConfiguration + d = &a + + case OptionVendorIdentifyingVendorClass: + d = &VIVCIdentifiers{} + + case OptionVendorSpecificInformation: + d = vendorDecoder + + case OptionClasslessStaticRoute: + d = &Routes{} + } + if d != nil && d.FromBytes(data) == nil { + return d + } + return OptionGeneric{data} +} diff --git a/vendor/github.com/insomniacslk/dhcp/dhcpv4/types.go b/vendor/github.com/insomniacslk/dhcp/dhcpv4/types.go new file mode 100644 index 000000000..80ea49cf8 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/dhcpv4/types.go @@ -0,0 +1,467 @@ +package dhcpv4 + +import ( + "fmt" + + "github.com/u-root/uio/uio" +) + +// values from http://www.networksorcery.com/enp/protocol/dhcp.htm and +// http://www.networksorcery.com/enp/protocol/bootp/options.htm + +// TransactionID represents a 4-byte DHCP transaction ID as defined in RFC 951, +// Section 3. +// +// The TransactionID is used to match DHCP replies to their original request. +type TransactionID [4]byte + +// String prints a hex transaction ID. +func (xid TransactionID) String() string { + return fmt.Sprintf("0x%x", xid[:]) +} + +// MessageType represents the possible DHCP message types - DISCOVER, OFFER, etc +type MessageType byte + +// DHCP message types +const ( + // MessageTypeNone is not a real message type, it is used by certain + // functions to signal that no explicit message type is requested + MessageTypeNone MessageType = 0 + MessageTypeDiscover MessageType = 1 + MessageTypeOffer MessageType = 2 + MessageTypeRequest MessageType = 3 + MessageTypeDecline MessageType = 4 + MessageTypeAck MessageType = 5 + MessageTypeNak MessageType = 6 + MessageTypeRelease MessageType = 7 + MessageTypeInform MessageType = 8 +) + +// ToBytes returns the serialized version of this option described by RFC 2132, +// Section 9.6. +func (m MessageType) ToBytes() []byte { + return []byte{byte(m)} +} + +// String prints a human-readable message type name. +func (m MessageType) String() string { + if s, ok := messageTypeToString[m]; ok { + return s + } + return fmt.Sprintf("unknown (%d)", byte(m)) +} + +// FromBytes reads a message type from data as described by RFC 2132, Section +// 9.6. +func (m *MessageType) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + *m = MessageType(buf.Read8()) + return buf.FinError() +} + +var messageTypeToString = map[MessageType]string{ + MessageTypeDiscover: "DISCOVER", + MessageTypeOffer: "OFFER", + MessageTypeRequest: "REQUEST", + MessageTypeDecline: "DECLINE", + MessageTypeAck: "ACK", + MessageTypeNak: "NAK", + MessageTypeRelease: "RELEASE", + MessageTypeInform: "INFORM", +} + +// OpcodeType represents a DHCPv4 opcode. +type OpcodeType uint8 + +// constants that represent valid values for OpcodeType +const ( + OpcodeBootRequest OpcodeType = 1 + OpcodeBootReply OpcodeType = 2 +) + +func (o OpcodeType) String() string { + if s, ok := opcodeToString[o]; ok { + return s + } + return fmt.Sprintf("unknown (%d)", uint8(o)) +} + +var opcodeToString = map[OpcodeType]string{ + OpcodeBootRequest: "BootRequest", + OpcodeBootReply: "BootReply", +} + +// OptionCode is a single byte representing the code for a given Option. +// +// OptionCode is an interface purely to support different stringers on options +// with the same Code value, as vendor-specific options use option codes that +// have the same value, but mean a different thing. +type OptionCode interface { + // Code is the 1 byte option code for the wire. + Code() uint8 + + // String returns the option's name. + String() string +} + +// optionCode is a DHCP option code. +type optionCode uint8 + +// Code implements OptionCode.Code. +func (o optionCode) Code() uint8 { + return uint8(o) +} + +// String returns an option name. +func (o optionCode) String() string { + if s, ok := optionCodeToString[o]; ok { + return s + } + return fmt.Sprintf("unknown (%d)", uint8(o)) +} + +// GenericOptionCode is an unnamed option code. +type GenericOptionCode uint8 + +// Code implements OptionCode.Code. +func (o GenericOptionCode) Code() uint8 { + return uint8(o) +} + +// String returns the option's name. +func (o GenericOptionCode) String() string { + return fmt.Sprintf("unknown (%d)", uint8(o)) +} + +// DHCPv4 Options +const ( + OptionPad optionCode = 0 + OptionSubnetMask optionCode = 1 + OptionTimeOffset optionCode = 2 + OptionRouter optionCode = 3 + OptionTimeServer optionCode = 4 + OptionNameServer optionCode = 5 + OptionDomainNameServer optionCode = 6 + OptionLogServer optionCode = 7 + OptionQuoteServer optionCode = 8 + OptionLPRServer optionCode = 9 + OptionImpressServer optionCode = 10 + OptionResourceLocationServer optionCode = 11 + OptionHostName optionCode = 12 + OptionBootFileSize optionCode = 13 + OptionMeritDumpFile optionCode = 14 + OptionDomainName optionCode = 15 + OptionSwapServer optionCode = 16 + OptionRootPath optionCode = 17 + OptionExtensionsPath optionCode = 18 + OptionIPForwarding optionCode = 19 + OptionNonLocalSourceRouting optionCode = 20 + OptionPolicyFilter optionCode = 21 + OptionMaximumDatagramAssemblySize optionCode = 22 + OptionDefaultIPTTL optionCode = 23 + OptionPathMTUAgingTimeout optionCode = 24 + OptionPathMTUPlateauTable optionCode = 25 + OptionInterfaceMTU optionCode = 26 + OptionAllSubnetsAreLocal optionCode = 27 + OptionBroadcastAddress optionCode = 28 + OptionPerformMaskDiscovery optionCode = 29 + OptionMaskSupplier optionCode = 30 + OptionPerformRouterDiscovery optionCode = 31 + OptionRouterSolicitationAddress optionCode = 32 + OptionStaticRoutingTable optionCode = 33 + OptionTrailerEncapsulation optionCode = 34 + OptionArpCacheTimeout optionCode = 35 + OptionEthernetEncapsulation optionCode = 36 + OptionDefaulTCPTTL optionCode = 37 + OptionTCPKeepaliveInterval optionCode = 38 + OptionTCPKeepaliveGarbage optionCode = 39 + OptionNetworkInformationServiceDomain optionCode = 40 + OptionNetworkInformationServers optionCode = 41 + OptionNTPServers optionCode = 42 + OptionVendorSpecificInformation optionCode = 43 + OptionNetBIOSOverTCPIPNameServer optionCode = 44 + OptionNetBIOSOverTCPIPDatagramDistributionServer optionCode = 45 + OptionNetBIOSOverTCPIPNodeType optionCode = 46 + OptionNetBIOSOverTCPIPScope optionCode = 47 + OptionXWindowSystemFontServer optionCode = 48 + OptionXWindowSystemDisplayManger optionCode = 49 + OptionRequestedIPAddress optionCode = 50 + OptionIPAddressLeaseTime optionCode = 51 + OptionOptionOverload optionCode = 52 + OptionDHCPMessageType optionCode = 53 + OptionServerIdentifier optionCode = 54 + OptionParameterRequestList optionCode = 55 + OptionMessage optionCode = 56 + OptionMaximumDHCPMessageSize optionCode = 57 + OptionRenewTimeValue optionCode = 58 + OptionRebindingTimeValue optionCode = 59 + OptionClassIdentifier optionCode = 60 + OptionClientIdentifier optionCode = 61 + OptionNetWareIPDomainName optionCode = 62 + OptionNetWareIPInformation optionCode = 63 + OptionNetworkInformationServicePlusDomain optionCode = 64 + OptionNetworkInformationServicePlusServers optionCode = 65 + OptionTFTPServerName optionCode = 66 + OptionBootfileName optionCode = 67 + OptionMobileIPHomeAgent optionCode = 68 + OptionSimpleMailTransportProtocolServer optionCode = 69 + OptionPostOfficeProtocolServer optionCode = 70 + OptionNetworkNewsTransportProtocolServer optionCode = 71 + OptionDefaultWorldWideWebServer optionCode = 72 + OptionDefaultFingerServer optionCode = 73 + OptionDefaultInternetRelayChatServer optionCode = 74 + OptionStreetTalkServer optionCode = 75 + OptionStreetTalkDirectoryAssistanceServer optionCode = 76 + OptionUserClassInformation optionCode = 77 + OptionSLPDirectoryAgent optionCode = 78 + OptionSLPServiceScope optionCode = 79 + OptionRapidCommit optionCode = 80 + OptionFQDN optionCode = 81 + OptionRelayAgentInformation optionCode = 82 + OptionInternetStorageNameService optionCode = 83 + // Option 84 returned in RFC 3679 + OptionNDSServers optionCode = 85 + OptionNDSTreeName optionCode = 86 + OptionNDSContext optionCode = 87 + OptionBCMCSControllerDomainNameList optionCode = 88 + OptionBCMCSControllerIPv4AddressList optionCode = 89 + OptionAuthentication optionCode = 90 + OptionClientLastTransactionTime optionCode = 91 + OptionAssociatedIP optionCode = 92 + OptionClientSystemArchitectureType optionCode = 93 + OptionClientNetworkInterfaceIdentifier optionCode = 94 + OptionLDAP optionCode = 95 + // Option 96 returned in RFC 3679 + OptionClientMachineIdentifier optionCode = 97 + OptionOpenGroupUserAuthentication optionCode = 98 + OptionGeoConfCivic optionCode = 99 + OptionIEEE10031TZString optionCode = 100 + OptionReferenceToTZDatabase optionCode = 101 + // Option 108 returned in RFC 8925 + OptionIPv6OnlyPreferred optionCode = 108 + // Options 102-111 returned in RFC 3679 + OptionNetInfoParentServerAddress optionCode = 112 + OptionNetInfoParentServerTag optionCode = 113 + OptionURL optionCode = 114 + // Option 115 returned in RFC 3679 + OptionAutoConfigure optionCode = 116 + OptionNameServiceSearch optionCode = 117 + OptionSubnetSelection optionCode = 118 + OptionDNSDomainSearchList optionCode = 119 + OptionSIPServers optionCode = 120 + OptionClasslessStaticRoute optionCode = 121 + OptionCCC optionCode = 122 + OptionGeoConf optionCode = 123 + OptionVendorIdentifyingVendorClass optionCode = 124 + OptionVendorIdentifyingVendorSpecific optionCode = 125 + // Options 126-127 returned in RFC 3679 + OptionTFTPServerIPAddress optionCode = 128 + OptionCallServerIPAddress optionCode = 129 + OptionDiscriminationString optionCode = 130 + OptionRemoteStatisticsServerIPAddress optionCode = 131 + Option8021PVLANID optionCode = 132 + Option8021QL2Priority optionCode = 133 + OptionDiffservCodePoint optionCode = 134 + OptionHTTPProxyForPhoneSpecificApplications optionCode = 135 + OptionPANAAuthenticationAgent optionCode = 136 + OptionLoSTServer optionCode = 137 + OptionCAPWAPAccessControllerAddresses optionCode = 138 + OptionOPTIONIPv4AddressMoS optionCode = 139 + OptionOPTIONIPv4FQDNMoS optionCode = 140 + OptionSIPUAConfigurationServiceDomains optionCode = 141 + OptionOPTIONIPv4AddressANDSF optionCode = 142 + OptionOPTIONIPv6AddressANDSF optionCode = 143 + // Options 144-149 returned in RFC 3679 + OptionTFTPServerAddress optionCode = 150 + OptionStatusCode optionCode = 151 + OptionBaseTime optionCode = 152 + OptionStartTimeOfState optionCode = 153 + OptionQueryStartTime optionCode = 154 + OptionQueryEndTime optionCode = 155 + OptionDHCPState optionCode = 156 + OptionDataSource optionCode = 157 + // Options 158-174 returned in RFC 3679 + OptionEtherboot optionCode = 175 + OptionIPTelephone optionCode = 176 + OptionEtherbootPacketCableAndCableHome optionCode = 177 + // Options 178-207 returned in RFC 3679 + OptionPXELinuxMagicString optionCode = 208 + OptionPXELinuxConfigFile optionCode = 209 + OptionPXELinuxPathPrefix optionCode = 210 + OptionPXELinuxRebootTime optionCode = 211 + OptionOPTION6RD optionCode = 212 + OptionOPTIONv4AccessDomain optionCode = 213 + // Options 214-219 returned in RFC 3679 + OptionSubnetAllocation optionCode = 220 + OptionVirtualSubnetAllocation optionCode = 221 + // Options 222-223 returned in RFC 3679 + // Options 224-254 are reserved for private use + OptionEnd optionCode = 255 +) + +var optionCodeToString = map[OptionCode]string{ + OptionPad: "Pad", + OptionSubnetMask: "Subnet Mask", + OptionTimeOffset: "Time Offset", + OptionRouter: "Router", + OptionTimeServer: "Time Server", + OptionNameServer: "Name Server", + OptionDomainNameServer: "Domain Name Server", + OptionLogServer: "Log Server", + OptionQuoteServer: "Quote Server", + OptionLPRServer: "LPR Server", + OptionImpressServer: "Impress Server", + OptionResourceLocationServer: "Resource Location Server", + OptionHostName: "Host Name", + OptionBootFileSize: "Boot File Size", + OptionMeritDumpFile: "Merit Dump File", + OptionDomainName: "Domain Name", + OptionSwapServer: "Swap Server", + OptionRootPath: "Root Path", + OptionExtensionsPath: "Extensions Path", + OptionIPForwarding: "IP Forwarding enable/disable", + OptionNonLocalSourceRouting: "Non-local Source Routing enable/disable", + OptionPolicyFilter: "Policy Filter", + OptionMaximumDatagramAssemblySize: "Maximum Datagram Reassembly Size", + OptionDefaultIPTTL: "Default IP Time-to-live", + OptionPathMTUAgingTimeout: "Path MTU Aging Timeout", + OptionPathMTUPlateauTable: "Path MTU Plateau Table", + OptionInterfaceMTU: "Interface MTU", + OptionAllSubnetsAreLocal: "All Subnets Are Local", + OptionBroadcastAddress: "Broadcast Address", + OptionPerformMaskDiscovery: "Perform Mask Discovery", + OptionMaskSupplier: "Mask Supplier", + OptionPerformRouterDiscovery: "Perform Router Discovery", + OptionRouterSolicitationAddress: "Router Solicitation Address", + OptionStaticRoutingTable: "Static Routing Table", + OptionTrailerEncapsulation: "Trailer Encapsulation", + OptionArpCacheTimeout: "ARP Cache Timeout", + OptionEthernetEncapsulation: "Ethernet Encapsulation", + OptionDefaulTCPTTL: "Default TCP TTL", + OptionTCPKeepaliveInterval: "TCP Keepalive Interval", + OptionTCPKeepaliveGarbage: "TCP Keepalive Garbage", + OptionNetworkInformationServiceDomain: "Network Information Service Domain", + OptionNetworkInformationServers: "Network Information Servers", + OptionNTPServers: "NTP Servers", + OptionVendorSpecificInformation: "Vendor Specific Information", + OptionNetBIOSOverTCPIPNameServer: "NetBIOS over TCP/IP Name Server", + OptionNetBIOSOverTCPIPDatagramDistributionServer: "NetBIOS over TCP/IP Datagram Distribution Server", + OptionNetBIOSOverTCPIPNodeType: "NetBIOS over TCP/IP Node Type", + OptionNetBIOSOverTCPIPScope: "NetBIOS over TCP/IP Scope", + OptionXWindowSystemFontServer: "X Window System Font Server", + OptionXWindowSystemDisplayManger: "X Window System Display Manager", + OptionRequestedIPAddress: "Requested IP Address", + OptionIPAddressLeaseTime: "IP Addresses Lease Time", + OptionOptionOverload: "Option Overload", + OptionDHCPMessageType: "DHCP Message Type", + OptionServerIdentifier: "Server Identifier", + OptionParameterRequestList: "Parameter Request List", + OptionMessage: "Message", + OptionMaximumDHCPMessageSize: "Maximum DHCP Message Size", + OptionRenewTimeValue: "Renew Time Value", + OptionRebindingTimeValue: "Rebinding Time Value", + OptionClassIdentifier: "Class Identifier", + OptionClientIdentifier: "Client identifier", + OptionNetWareIPDomainName: "NetWare/IP Domain Name", + OptionNetWareIPInformation: "NetWare/IP Information", + OptionNetworkInformationServicePlusDomain: "Network Information Service+ Domain", + OptionNetworkInformationServicePlusServers: "Network Information Service+ Servers", + OptionTFTPServerName: "TFTP Server Name", + OptionBootfileName: "Bootfile Name", + OptionMobileIPHomeAgent: "Mobile IP Home Agent", + OptionSimpleMailTransportProtocolServer: "SMTP Server", + OptionPostOfficeProtocolServer: "POP Server", + OptionNetworkNewsTransportProtocolServer: "NNTP Server", + OptionDefaultWorldWideWebServer: "Default WWW Server", + OptionDefaultFingerServer: "Default Finger Server", + OptionDefaultInternetRelayChatServer: "Default IRC Server", + OptionStreetTalkServer: "StreetTalk Server", + OptionStreetTalkDirectoryAssistanceServer: "StreetTalk Directory Assistance Server", + OptionUserClassInformation: "User Class Information", + OptionSLPDirectoryAgent: "SLP DIrectory Agent", + OptionSLPServiceScope: "SLP Service Scope", + OptionRapidCommit: "Rapid Commit", + OptionFQDN: "FQDN", + OptionRelayAgentInformation: "Relay Agent Information", + OptionInternetStorageNameService: "Internet Storage Name Service", + // Option 84 returned in RFC 3679 + OptionNDSServers: "NDS Servers", + OptionNDSTreeName: "NDS Tree Name", + OptionNDSContext: "NDS Context", + OptionBCMCSControllerDomainNameList: "BCMCS Controller Domain Name List", + OptionBCMCSControllerIPv4AddressList: "BCMCS Controller IPv4 Address List", + OptionAuthentication: "Authentication", + OptionClientLastTransactionTime: "Client Last Transaction Time", + OptionAssociatedIP: "Associated IP", + OptionClientSystemArchitectureType: "Client System Architecture Type", + OptionClientNetworkInterfaceIdentifier: "Client Network Interface Identifier", + OptionLDAP: "LDAP", + // Option 96 returned in RFC 3679 + OptionClientMachineIdentifier: "Client Machine Identifier", + OptionOpenGroupUserAuthentication: "OpenGroup's User Authentication", + OptionGeoConfCivic: "GEOCONF_CIVIC", + OptionIEEE10031TZString: "IEEE 1003.1 TZ String", + OptionReferenceToTZDatabase: "Reference to the TZ Database", + // Option 108 returned in RFC 8925 + OptionIPv6OnlyPreferred: "IPv6-Only Preferred", + // Options 102-111 returned in RFC 3679 + OptionNetInfoParentServerAddress: "NetInfo Parent Server Address", + OptionNetInfoParentServerTag: "NetInfo Parent Server Tag", + OptionURL: "URL", + // Option 115 returned in RFC 3679 + OptionAutoConfigure: "Auto-Configure", + OptionNameServiceSearch: "Name Service Search", + OptionSubnetSelection: "Subnet Selection", + OptionDNSDomainSearchList: "DNS Domain Search List", + OptionSIPServers: "SIP Servers", + OptionClasslessStaticRoute: "Classless Static Route", + OptionCCC: "CCC, CableLabs Client Configuration", + OptionGeoConf: "GeoConf", + OptionVendorIdentifyingVendorClass: "Vendor-Identifying Vendor Class", + OptionVendorIdentifyingVendorSpecific: "Vendor-Identifying Vendor-Specific", + // Options 126-127 returned in RFC 3679 + OptionTFTPServerIPAddress: "TFTP Server IP Address", + OptionCallServerIPAddress: "Call Server IP Address", + OptionDiscriminationString: "Discrimination String", + OptionRemoteStatisticsServerIPAddress: "RemoteStatistics Server IP Address", + Option8021PVLANID: "802.1P VLAN ID", + Option8021QL2Priority: "802.1Q L2 Priority", + OptionDiffservCodePoint: "Diffserv Code Point", + OptionHTTPProxyForPhoneSpecificApplications: "HTTP Proxy for phone-specific applications", + OptionPANAAuthenticationAgent: "PANA Authentication Agent", + OptionLoSTServer: "LoST Server", + OptionCAPWAPAccessControllerAddresses: "CAPWAP Access Controller Addresses", + OptionOPTIONIPv4AddressMoS: "OPTION-IPv4_Address-MoS", + OptionOPTIONIPv4FQDNMoS: "OPTION-IPv4_FQDN-MoS", + OptionSIPUAConfigurationServiceDomains: "SIP UA Configuration Service Domains", + OptionOPTIONIPv4AddressANDSF: "OPTION-IPv4_Address-ANDSF", + OptionOPTIONIPv6AddressANDSF: "OPTION-IPv6_Address-ANDSF", + // Options 144-149 returned in RFC 3679 + OptionTFTPServerAddress: "TFTP Server Address", + OptionStatusCode: "Status Code", + OptionBaseTime: "Base Time", + OptionStartTimeOfState: "Start Time of State", + OptionQueryStartTime: "Query Start Time", + OptionQueryEndTime: "Query End Time", + OptionDHCPState: "DHCP Staet", + OptionDataSource: "Data Source", + // Options 158-174 returned in RFC 3679 + OptionEtherboot: "Etherboot", + OptionIPTelephone: "IP Telephone", + OptionEtherbootPacketCableAndCableHome: "Etherboot / PacketCable and CableHome", + // Options 178-207 returned in RFC 3679 + OptionPXELinuxMagicString: "PXELinux Magic String", + OptionPXELinuxConfigFile: "PXELinux Config File", + OptionPXELinuxPathPrefix: "PXELinux Path Prefix", + OptionPXELinuxRebootTime: "PXELinux Reboot Time", + OptionOPTION6RD: "OPTION_6RD", + OptionOPTIONv4AccessDomain: "OPTION_V4_ACCESS_DOMAIN", + // Options 214-219 returned in RFC 3679 + OptionSubnetAllocation: "Subnet Allocation", + OptionVirtualSubnetAllocation: "Virtual Subnet Selection", + // Options 222-223 returned in RFC 3679 + // Options 224-254 are reserved for private use + + OptionEnd: "End", +} diff --git a/vendor/github.com/insomniacslk/dhcp/iana/archtype.go b/vendor/github.com/insomniacslk/dhcp/iana/archtype.go new file mode 100644 index 000000000..d85870ccd --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/iana/archtype.go @@ -0,0 +1,148 @@ +package iana + +import ( + "fmt" + "strings" + + "github.com/u-root/uio/uio" +) + +// Arch encodes an architecture type per RFC 4578, Section 2.1. +type Arch uint16 + +// See RFC 4578, 5970, and http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#processor-architecture +const ( + INTEL_X86PC Arch = 0 + NEC_PC98 Arch = 1 + EFI_ITANIUM Arch = 2 + DEC_ALPHA Arch = 3 + ARC_X86 Arch = 4 + INTEL_LEAN_CLIENT Arch = 5 + EFI_IA32 Arch = 6 + EFI_X86_64 Arch = 7 + EFI_XSCALE Arch = 8 + EFI_BC Arch = 9 + EFI_ARM32 Arch = 10 + EFI_ARM64 Arch = 11 + PPC_OPEN_FIRMWARE Arch = 12 + PPC_EPAPR Arch = 13 + PPC_OPAL Arch = 14 + EFI_X86_HTTP Arch = 15 + EFI_X86_64_HTTP Arch = 16 + EFI_BC_HTTP Arch = 17 + EFI_ARM32_HTTP Arch = 18 + EFI_ARM64_HTTP Arch = 19 + INTEL_X86PC_HTTP Arch = 20 + UBOOT_ARM32 Arch = 21 + UBOOT_ARM64 Arch = 22 + UBOOT_ARM32_HTTP Arch = 23 + UBOOT_ARM64_HTTP Arch = 24 + EFI_RISCV32 Arch = 25 + EFI_RISCV32_HTTP Arch = 26 + EFI_RISCV64 Arch = 27 + EFI_RISCV64_HTTP Arch = 28 + EFI_RISCV128 Arch = 29 + EFI_RISCV128_HTTP Arch = 30 + S390_BASIC Arch = 31 + S390_EXTENDED Arch = 32 + EFI_MIPS32 Arch = 33 + EFI_MIPS64 Arch = 34 + EFI_SUNWAY32 Arch = 35 + EFI_SUNWAY64 Arch = 36 +) + +// archTypeToStringMap maps an Arch to a mnemonic name +var archTypeToStringMap = map[Arch]string{ + INTEL_X86PC: "Intel x86PC", + NEC_PC98: "NEC/PC98", + EFI_ITANIUM: "EFI Itanium", + DEC_ALPHA: "DEC Alpha", + ARC_X86: "Arc x86", + INTEL_LEAN_CLIENT: "Intel Lean Client", + EFI_IA32: "EFI IA32", + EFI_XSCALE: "EFI Xscale", + EFI_X86_64: "EFI x86-64", + EFI_BC: "EFI BC", + EFI_ARM32: "EFI ARM32", + EFI_ARM64: "EFI ARM64", + PPC_OPEN_FIRMWARE: "PowerPC Open Firmware", + PPC_EPAPR: "PowerPC ePAPR", + PPC_OPAL: "POWER OPAL v3", + EFI_X86_HTTP: "EFI x86 boot from HTTP", + EFI_X86_64_HTTP: "EFI x86-64 boot from HTTP", + EFI_BC_HTTP: "EFI BC boot from HTTP", + EFI_ARM32_HTTP: "EFI ARM32 boot from HTTP", + EFI_ARM64_HTTP: "EFI ARM64 boot from HTTP", + INTEL_X86PC_HTTP: "Intel x86PC boot from HTTP", + UBOOT_ARM32: "U-Boot ARM32", + UBOOT_ARM64: "U-Boot ARM64", + UBOOT_ARM32_HTTP: "U-boot ARM32 boot from HTTP", + UBOOT_ARM64_HTTP: "U-Boot ARM64 boot from HTTP", + EFI_RISCV32: "EFI RISC-V 32-bit", + EFI_RISCV32_HTTP: "EFI RISC-V 32-bit boot from HTTP", + EFI_RISCV64: "EFI RISC-V 64-bit", + EFI_RISCV64_HTTP: "EFI RISC-V 64-bit boot from HTTP", + EFI_RISCV128: "EFI RISC-V 128-bit", + EFI_RISCV128_HTTP: "EFI RISC-V 128-bit boot from HTTP", + S390_BASIC: "s390 Basic", + S390_EXTENDED: "s390 Extended", + EFI_MIPS32: "EFI MIPS32", + EFI_MIPS64: "EFI MIPS64", + EFI_SUNWAY32: "EFI Sunway 32-bit", + EFI_SUNWAY64: "EFI Sunway 64-bit", +} + +// String returns a mnemonic name for a given architecture type. +func (a Arch) String() string { + if at := archTypeToStringMap[a]; at != "" { + return at + } + return "unknown" +} + +// Archs represents multiple Arch values. +type Archs []Arch + +// Contains returns whether b is one of the Archs in a. +func (a Archs) Contains(b Arch) bool { + for _, t := range a { + if t == b { + return true + } + } + return false +} + +// ToBytes returns the serialized option defined by RFC 4578 (DHCPv4) and RFC +// 5970 (DHCPv6) as the Client System Architecture Option. +func (a Archs) ToBytes() []byte { + buf := uio.NewBigEndianBuffer(nil) + for _, at := range a { + buf.Write16(uint16(at)) + } + return buf.Data() +} + +// String returns the list of archs in a human-readable manner. +func (a Archs) String() string { + s := make([]string, 0, len(a)) + for _, arch := range a { + s = append(s, arch.String()) + } + return strings.Join(s, ", ") +} + +// FromBytes parses a DHCP list of architecture types as defined by RFC 4578 +// and RFC 5970. +func (a *Archs) FromBytes(data []byte) error { + buf := uio.NewBigEndianBuffer(data) + if buf.Len() == 0 { + return fmt.Errorf("must have at least one archtype if option is present") + } + + *a = make([]Arch, 0, buf.Len()/2) + for buf.Has(2) { + *a = append(*a, Arch(buf.Read16())) + } + return buf.FinError() +} diff --git a/vendor/github.com/insomniacslk/dhcp/iana/entid.go b/vendor/github.com/insomniacslk/dhcp/iana/entid.go new file mode 100644 index 000000000..6aa318c69 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/iana/entid.go @@ -0,0 +1,25 @@ +package iana + +// EnterpriseID represents the Enterprise IDs as set by IANA +type EnterpriseID int + +// See https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers for values +const ( + EnterpriseIDCiscoSystems EnterpriseID = 9 + EnterpriseIDCienaCorporation EnterpriseID = 1271 + EnterpriseIDMellanoxTechnologiesLTD EnterpriseID = 33049 +) + +var enterpriseIDToStringMap = map[EnterpriseID]string{ + EnterpriseIDCiscoSystems: "Cisco Systems", + EnterpriseIDCienaCorporation: "Ciena Corporation", + EnterpriseIDMellanoxTechnologiesLTD: "Mellanox Technologies LTD", +} + +// String returns the vendor name for a given Enterprise ID +func (e EnterpriseID) String() string { + if vendor := enterpriseIDToStringMap[e]; vendor != "" { + return vendor + } + return "Unknown" +} diff --git a/vendor/github.com/insomniacslk/dhcp/iana/hwtypes.go b/vendor/github.com/insomniacslk/dhcp/iana/hwtypes.go new file mode 100644 index 000000000..e6fb38b23 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/iana/hwtypes.go @@ -0,0 +1,91 @@ +package iana + +// HWType is a hardware type as per RFC 2132 and defined by the IANA. +type HWType uint16 + +// See IANA for values. +const ( + _ HWType = iota // skip 0 + HWTypeEthernet + HWTypeExperimentalEthernet + HWTypeAmateurRadioAX25 + HWTypeProteonTokenRing + HWTypeChaos + HWTypeIEEE802 + HWTypeARCNET + HWTypeHyperchannel + HWTypeLanstar + HWTypeAutonet + HWTypeLocalTalk + HWTypeLocalNet + HWTypeUltraLink + HWTypeSMDS + HWTypeFrameRelay + HWTypeATM + HWTypeHDLC + HWTypeFibreChannel + HWTypeATM2 + HWTypeSerialLine + HWTypeATM3 + HWTypeMILSTD188220 + HWTypeMetricom + HWTypeIEEE1394 + HWTypeMAPOS + HWTypeTwinaxial + HWTypeEUI64 + HWTypeHIPARP + HWTypeISO7816 + HWTypeARPSec + HWTypeIPsec + HWTypeInfiniband + HWTypeCAI + HWTypeWiegandInterface + HWTypePureIP +) + +var hwTypeToString = map[HWType]string{ + HWTypeEthernet: "Ethernet", + HWTypeExperimentalEthernet: "Experimental Ethernet", + HWTypeAmateurRadioAX25: "Amateur Radio AX.25", + HWTypeProteonTokenRing: "Proteon ProNET Token Ring", + HWTypeChaos: "Chaos", + HWTypeIEEE802: "IEEE 802", + HWTypeARCNET: "ARCNET", + HWTypeHyperchannel: "Hyperchannel", + HWTypeLanstar: "Lanstar", + HWTypeAutonet: "Autonet Short Address", + HWTypeLocalTalk: "LocalTalk", + HWTypeLocalNet: "LocalNet", + HWTypeUltraLink: "Ultra link", + HWTypeSMDS: "SMDS", + HWTypeFrameRelay: "Frame Relay", + HWTypeATM: "ATM", + HWTypeHDLC: "HDLC", + HWTypeFibreChannel: "Fibre Channel", + HWTypeATM2: "ATM 2", + HWTypeSerialLine: "Serial Line", + HWTypeATM3: "ATM 3", + HWTypeMILSTD188220: "MIL-STD-188-220", + HWTypeMetricom: "Metricom", + HWTypeIEEE1394: "IEEE 1394.1995", + HWTypeMAPOS: "MAPOS", + HWTypeTwinaxial: "Twinaxial", + HWTypeEUI64: "EUI-64", + HWTypeHIPARP: "HIPARP", + HWTypeISO7816: "IP and ARP over ISO 7816-3", + HWTypeARPSec: "ARPSec", + HWTypeIPsec: "IPsec tunnel", + HWTypeInfiniband: "Infiniband", + HWTypeCAI: "CAI, TIA-102 Project 125 Common Air Interface", + HWTypeWiegandInterface: "Wiegand Interface", + HWTypePureIP: "Pure IP", +} + +// String implements fmt.Stringer. +func (h HWType) String() string { + hwtype := hwTypeToString[h] + if hwtype == "" { + hwtype = "unknown" + } + return hwtype +} diff --git a/vendor/github.com/insomniacslk/dhcp/iana/iana.go b/vendor/github.com/insomniacslk/dhcp/iana/iana.go new file mode 100644 index 000000000..e0d5956cf --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/iana/iana.go @@ -0,0 +1,2 @@ +// Package iana contains constants defined by IANA. +package iana diff --git a/vendor/github.com/insomniacslk/dhcp/iana/statuscodes.go b/vendor/github.com/insomniacslk/dhcp/iana/statuscodes.go new file mode 100644 index 000000000..ee45820a4 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/iana/statuscodes.go @@ -0,0 +1,77 @@ +package iana + +// StatusCode represents a IANA status code for DHCPv6 +// +// IANA Status Codes for DHCPv6 +// https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-5 +type StatusCode uint16 + +// IANA status codes +const ( + // RFC 3315 par. 24..4 + StatusSuccess StatusCode = 0 + StatusUnspecFail StatusCode = 1 + StatusNoAddrsAvail StatusCode = 2 + StatusNoBinding StatusCode = 3 + StatusNotOnLink StatusCode = 4 + StatusUseMulticast StatusCode = 5 + StatusNoPrefixAvail StatusCode = 6 + // RFC 5007 + StatusUnknownQueryType StatusCode = 7 + StatusMalformedQuery StatusCode = 8 + StatusNotConfigured StatusCode = 9 + StatusNotAllowed StatusCode = 10 + // RFC 5460 + StatusQueryTerminated StatusCode = 11 + // RFC 7653 + StatusDataMissing StatusCode = 12 + StatusCatchUpComplete StatusCode = 13 + StatusNotSupported StatusCode = 14 + StatusTLSConnectionRefused StatusCode = 15 + // RFC 8156 + StatusAddressInUse StatusCode = 16 + StatusConfigurationConflict StatusCode = 17 + StatusMissingBindingInformation StatusCode = 18 + StatusOutdatedBindingInformation StatusCode = 19 + StatusServerShuttingDown StatusCode = 20 + StatusDNSUpdateNotSupported StatusCode = 21 + StatusExcessiveTimeSkew StatusCode = 22 +) + +// String returns a mnemonic name for a given status code +func (s StatusCode) String() string { + if sc := statusCodeToStringMap[s]; sc != "" { + return sc + } + return "Unknown" +} + +var statusCodeToStringMap = map[StatusCode]string{ + StatusSuccess: "Success", + StatusUnspecFail: "UnspecFail", + StatusNoAddrsAvail: "NoAddrsAvail", + StatusNoBinding: "NoBinding", + StatusNotOnLink: "NotOnLink", + StatusUseMulticast: "UseMulticast", + StatusNoPrefixAvail: "NoPrefixAvail", + // RFC 5007 + StatusUnknownQueryType: "UnknownQueryType", + StatusMalformedQuery: "MalformedQuery", + StatusNotConfigured: "NotConfigured", + StatusNotAllowed: "NotAllowed", + // RFC 5460 + StatusQueryTerminated: "QueryTerminated", + // RFC 7653 + StatusDataMissing: "DataMissing", + StatusCatchUpComplete: "CatchUpComplete", + StatusNotSupported: "NotSupported", + StatusTLSConnectionRefused: "TLSConnectionRefused", + // RFC 8156 + StatusAddressInUse: "AddressInUse", + StatusConfigurationConflict: "ConfigurationConflict", + StatusMissingBindingInformation: "MissingBindingInformation", + StatusOutdatedBindingInformation: "OutdatedBindingInformation", + StatusServerShuttingDown: "ServerShuttingDown", + StatusDNSUpdateNotSupported: "DNSUpdateNotSupported", + StatusExcessiveTimeSkew: "ExcessiveTimeSkew", +} diff --git a/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_bsd.go b/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_bsd.go new file mode 100644 index 000000000..7dbfd3fb9 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_bsd.go @@ -0,0 +1,19 @@ +// +build aix freebsd openbsd netbsd dragonfly + +package interfaces + +import ( + "net" + + "golang.org/x/sys/unix" +) + +// BindToInterface emulates linux's SO_BINDTODEVICE option for a socket by using +// IP_RECVIF. +func BindToInterface(fd int, ifname string) error { + iface, err := net.InterfaceByName(ifname) + if err != nil { + return err + } + return unix.SetsockoptInt(fd, unix.IPPROTO_IP, unix.IP_RECVIF, iface.Index) +} diff --git a/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_darwin.go b/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_darwin.go new file mode 100644 index 000000000..5ddfc0e3f --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_darwin.go @@ -0,0 +1,19 @@ +// +build darwin + +package interfaces + +import ( + "net" + + "golang.org/x/sys/unix" +) + +// BindToInterface emulates linux's SO_BINDTODEVICE option for a socket by using +// IP_BOUND_IF. +func BindToInterface(fd int, ifname string) error { + iface, err := net.InterfaceByName(ifname) + if err != nil { + return err + } + return unix.SetsockoptInt(fd, unix.IPPROTO_IP, unix.IP_BOUND_IF, iface.Index) +} diff --git a/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_linux.go b/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_linux.go new file mode 100644 index 000000000..52c7177bf --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_linux.go @@ -0,0 +1,9 @@ +// +build linux + +package interfaces + +import "golang.org/x/sys/unix" + +func BindToInterface(fd int, ifname string) error { + return unix.BindToDevice(fd, ifname) +} diff --git a/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_windows.go b/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_windows.go new file mode 100644 index 000000000..6de9b4d03 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/interfaces/bindtodevice_windows.go @@ -0,0 +1,8 @@ +package interfaces + +import "errors" + +// BindToInterface fails on Windows. +func BindToInterface(fd int, ifname string) error { + return errors.New("not implemented on Windows") +} diff --git a/vendor/github.com/insomniacslk/dhcp/interfaces/interfaces.go b/vendor/github.com/insomniacslk/dhcp/interfaces/interfaces.go new file mode 100644 index 000000000..5761669f0 --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/interfaces/interfaces.go @@ -0,0 +1,41 @@ +package interfaces + +import "net" + +// InterfaceMatcher is a function type used to match the interfaces we want. See +// GetInterfacesFunc below for usage. +type InterfaceMatcher func(net.Interface) bool + +// interfaceGetter is used for testing purposes +var interfaceGetter = net.Interfaces + +// GetInterfacesFunc loops through the available network interfaces, and returns +// a list of interfaces for which the passed InterfaceMatcher function returns +// true. +func GetInterfacesFunc(matcher InterfaceMatcher) ([]net.Interface, error) { + ifaces, err := interfaceGetter() + if err != nil { + return nil, err + } + ret := make([]net.Interface, 0) + for _, iface := range ifaces { + if matcher(iface) { + ret = append(ret, iface) + } + } + return ret, nil +} + +// GetLoopbackInterfaces returns a list of loopback interfaces. +func GetLoopbackInterfaces() ([]net.Interface, error) { + return GetInterfacesFunc(func(iface net.Interface) bool { + return iface.Flags&net.FlagLoopback != 0 + }) +} + +// GetNonLoopbackInterfaces returns a list of non-loopback interfaces. +func GetNonLoopbackInterfaces() ([]net.Interface, error) { + return GetInterfacesFunc(func(iface net.Interface) bool { + return iface.Flags&net.FlagLoopback == 0 + }) +} diff --git a/vendor/github.com/insomniacslk/dhcp/rfc1035label/label.go b/vendor/github.com/insomniacslk/dhcp/rfc1035label/label.go new file mode 100644 index 000000000..f727ec6eb --- /dev/null +++ b/vendor/github.com/insomniacslk/dhcp/rfc1035label/label.go @@ -0,0 +1,173 @@ +package rfc1035label + +import ( + "errors" + "fmt" + "strings" +) + +// Labels represents RFC1035 labels +// +// This implements RFC 1035 labels, including compression. +// https://tools.ietf.org/html/rfc1035#section-4.1.4 +type Labels struct { + // original contains the original bytes if the object was parsed from a byte + // sequence, or nil otherwise. The `original` field is necessary to deal + // with compressed labels. If the labels are further modified, the original + // content is invalidated and no compression will be used. + original []byte + // Labels contains the parsed labels. A change here invalidates the + // `original` object. + Labels []string +} + +// same compares two string arrays +func same(a, b []string) bool { + if len(a) != len(b) { + return false + } + for i := 0; i < len(a); i++ { + if a[i] != b[i] { + return false + } + } + return true +} + +// String prints labels. +func (l *Labels) String() string { + return fmt.Sprintf("%v", l.Labels) +} + +// ToBytes returns a byte sequence representing the labels. If the original +// sequence is modified, the labels are parsed again, otherwise the original +// byte sequence is returned. +func (l *Labels) ToBytes() []byte { + // if the original byte sequence has been modified, invalidate it and + // serialize again. + // NOTE: this function is not thread-safe. If multiple threads modify + // the `Labels` field, the result may be wrong. + originalLabels, err := labelsFromBytes(l.original) + // if the original object has not been modified, or we cannot parse it, + // return the original bytes. + if err != nil || (l.original != nil && same(originalLabels, l.Labels)) { + return l.original + } + return labelsToBytes(l.Labels) +} + +// Length returns the length in bytes of the serialized labels +func (l *Labels) Length() int { + return len(l.ToBytes()) +} + +// NewLabels returns an initialized Labels object. +func NewLabels() *Labels { + return &Labels{ + Labels: make([]string, 0), + } +} + +// FromBytes reads labels from a bytes stream according to RFC 1035. +func (l *Labels) FromBytes(data []byte) error { + labs, err := labelsFromBytes(data) + if err != nil { + return err + } + l.original = data + l.Labels = labs + return nil +} + +// FromBytes returns a Labels object from the given byte sequence, or an error if +// any. +func FromBytes(data []byte) (*Labels, error) { + var l Labels + if err := l.FromBytes(data); err != nil { + return nil, err + } + return &l, nil +} + +// ErrBufferTooShort is returned when the label cannot be parsed due to a wrong +// length or missing bytes. +var ErrBufferTooShort = errors.New("rfc1035label: buffer too short") + +// fromBytes decodes a serialized stream and returns a list of labels +func labelsFromBytes(buf []byte) ([]string, error) { + var ( + labels = make([]string, 0) + pos, oldPos int + label string + handlingPointer bool + ) + + for { + if pos >= len(buf) { + // interpret label without trailing zero-length byte as a partial + // domain name field as per RFC 4704 Section 4.2 + if label != "" { + labels = append(labels, label) + } + + break + } + length := int(buf[pos]) + pos++ + var chunk string + if length == 0 { + labels = append(labels, label) + label = "" + if handlingPointer { + pos = oldPos + handlingPointer = false + } + } else if length&0xc0 == 0xc0 { + // compression pointer + if handlingPointer { + return nil, errors.New("rfc1035label: cannot handle nested pointers") + } + handlingPointer = true + if pos+1 > len(buf) { + return nil, errors.New("rfc1035label: pointer buffer too short") + } + off := int(buf[pos-1]&^0xc0)<<8 + int(buf[pos]) + oldPos = pos + 1 + pos = off + } else { + if pos+length > len(buf) { + return nil, ErrBufferTooShort + } + chunk = string(buf[pos : pos+length]) + if label != "" { + label += "." + } + label += chunk + pos += length + } + } + return labels, nil +} + +// labelToBytes encodes a label and returns a serialized stream of bytes +func labelToBytes(label string) []byte { + var encodedLabel []byte + if len(label) == 0 { + return []byte{0} + } + for _, part := range strings.Split(label, ".") { + encodedLabel = append(encodedLabel, byte(len(part))) + encodedLabel = append(encodedLabel, []byte(part)...) + } + return append(encodedLabel, 0) +} + +// labelsToBytes encodes a list of labels and returns a serialized stream of +// bytes +func labelsToBytes(labels []string) []byte { + var encodedLabels []byte + for _, label := range labels { + encodedLabels = append(encodedLabels, labelToBytes(label)...) + } + return encodedLabels +} diff --git a/vendor/github.com/josharian/native/doc.go b/vendor/github.com/josharian/native/doc.go new file mode 100644 index 000000000..2ca7ddc8a --- /dev/null +++ b/vendor/github.com/josharian/native/doc.go @@ -0,0 +1,8 @@ +// Package native provides easy access to native byte order. +// +// Usage: use native.Endian where you need the native binary.ByteOrder. +// +// Please think twice before using this package. +// It can break program portability. +// Native byte order is usually not the right answer. +package native diff --git a/vendor/github.com/josharian/native/endian_big.go b/vendor/github.com/josharian/native/endian_big.go new file mode 100644 index 000000000..77744fdd4 --- /dev/null +++ b/vendor/github.com/josharian/native/endian_big.go @@ -0,0 +1,14 @@ +//go:build mips || mips64 || ppc64 || s390x +// +build mips mips64 ppc64 s390x + +package native + +import "encoding/binary" + +// Endian is the encoding/binary.ByteOrder implementation for the +// current CPU's native byte order. +var Endian = binary.BigEndian + +// IsBigEndian is whether the current CPU's native byte order is big +// endian. +const IsBigEndian = true diff --git a/vendor/github.com/josharian/native/endian_generic.go b/vendor/github.com/josharian/native/endian_generic.go new file mode 100644 index 000000000..c15228f31 --- /dev/null +++ b/vendor/github.com/josharian/native/endian_generic.go @@ -0,0 +1,31 @@ +//go:build !mips && !mips64 && !ppc64 && !s390x && !amd64 && !386 && !arm && !arm64 && !loong64 && !mipsle && !mips64le && !ppc64le && !riscv64 && !wasm +// +build !mips,!mips64,!ppc64,!s390x,!amd64,!386,!arm,!arm64,!loong64,!mipsle,!mips64le,!ppc64le,!riscv64,!wasm + +// This file is a fallback, so that package native doesn't break +// the instant the Go project adds support for a new architecture. +// + +package native + +import ( + "encoding/binary" + "log" + "runtime" + "unsafe" +) + +var Endian binary.ByteOrder + +var IsBigEndian bool + +func init() { + b := uint16(0xff) // one byte + if *(*byte)(unsafe.Pointer(&b)) == 0 { + Endian = binary.BigEndian + IsBigEndian = true + } else { + Endian = binary.LittleEndian + IsBigEndian = false + } + log.Printf("github.com/josharian/native: unrecognized arch %v (%v), please file an issue", runtime.GOARCH, Endian) +} diff --git a/vendor/github.com/josharian/native/endian_little.go b/vendor/github.com/josharian/native/endian_little.go new file mode 100644 index 000000000..5098fec26 --- /dev/null +++ b/vendor/github.com/josharian/native/endian_little.go @@ -0,0 +1,14 @@ +//go:build amd64 || 386 || arm || arm64 || loong64 || mipsle || mips64le || ppc64le || riscv64 || wasm +// +build amd64 386 arm arm64 loong64 mipsle mips64le ppc64le riscv64 wasm + +package native + +import "encoding/binary" + +// Endian is the encoding/binary.ByteOrder implementation for the +// current CPU's native byte order. +var Endian = binary.LittleEndian + +// IsBigEndian is whether the current CPU's native byte order is big +// endian. +const IsBigEndian = false diff --git a/vendor/github.com/josharian/native/license b/vendor/github.com/josharian/native/license new file mode 100644 index 000000000..6e617a9c7 --- /dev/null +++ b/vendor/github.com/josharian/native/license @@ -0,0 +1,7 @@ +Copyright 2020 Josh Bleecher Snyder + +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: + +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. diff --git a/vendor/github.com/josharian/native/readme.md b/vendor/github.com/josharian/native/readme.md new file mode 100644 index 000000000..1fc5a01b8 --- /dev/null +++ b/vendor/github.com/josharian/native/readme.md @@ -0,0 +1,10 @@ +Package native provides easy access to native byte order. + +`go get github.com/josharian/native` + +Usage: Use `native.Endian` where you need the native binary.ByteOrder. + +Please think twice before using this package. +It can break program portability. +Native byte order is usually not the right answer. + diff --git a/vendor/github.com/mdlayher/packet/.gitignore b/vendor/github.com/mdlayher/packet/.gitignore new file mode 100644 index 000000000..945907274 --- /dev/null +++ b/vendor/github.com/mdlayher/packet/.gitignore @@ -0,0 +1 @@ +cmd/packet diff --git a/vendor/github.com/mdlayher/packet/CHANGELOG.md b/vendor/github.com/mdlayher/packet/CHANGELOG.md new file mode 100644 index 000000000..4124bd9b6 --- /dev/null +++ b/vendor/github.com/mdlayher/packet/CHANGELOG.md @@ -0,0 +1,27 @@ +# CHANGELOG + +# v1.1.2 + +- [Improvement]: updated dependencies, test with Go 1.20. + +# v1.1.1 + +- [Bug Fix]: fix test compilation on big endian machines. + +# v1.1.0 + +**This is the first release of package packet that only supports Go 1.18+. Users +on older versions of Go must use v1.0.0.** + +- [Improvement]: drop support for older versions of Go so we can begin using + modern versions of `x/sys` and other dependencies. + +## v1.0.0 + +**This is the last release of package vsock that supports Go 1.17 and below.** + +- Initial stable commit! The API is mostly a direct translation of the previous + `github.com/mdlayher/raw` package APIs, with some updates to make everything + focused explicitly on Linux and `AF_PACKET` sockets. Functionally, the two + packages are equivalent, and `*raw.Conn` is now backed by `*packet.Conn` in + the latest version of the `raw` package. diff --git a/vendor/github.com/mdlayher/packet/LICENSE.md b/vendor/github.com/mdlayher/packet/LICENSE.md new file mode 100644 index 000000000..98382a3d9 --- /dev/null +++ b/vendor/github.com/mdlayher/packet/LICENSE.md @@ -0,0 +1,9 @@ +# MIT License + +Copyright (C) 2022 Matt Layher + +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: + +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. diff --git a/vendor/github.com/mdlayher/packet/README.md b/vendor/github.com/mdlayher/packet/README.md new file mode 100644 index 000000000..ddb90074a --- /dev/null +++ b/vendor/github.com/mdlayher/packet/README.md @@ -0,0 +1,35 @@ +# packet [![Test Status](https://github.com/mdlayher/packet/workflows/Test/badge.svg)](https://github.com/mdlayher/packet/actions) [![Go Reference](https://pkg.go.dev/badge/github.com/mdlayher/packet.svg)](https://pkg.go.dev/github.com/mdlayher/packet) [![Go Report Card](https://goreportcard.com/badge/github.com/mdlayher/packet)](https://goreportcard.com/report/github.com/mdlayher/packet) + +Package `packet` provides access to Linux packet sockets (`AF_PACKET`). MIT +Licensed. + +## Stability + +See the [CHANGELOG](./CHANGELOG.md) file for a description of changes between +releases. + +This package has a stable v1 API and any future breaking changes will prompt +the release of a new major version. Features and bug fixes will continue to +occur in the v1.x.x series. + +This package only supports the two most recent major versions of Go, mirroring +Go's own release policy. Older versions of Go may lack critical features and bug +fixes which are necessary for this package to function correctly. + +## History + +One of my first major Go networking projects was +[`github.com/mdlayher/raw`](https://github.com/mdlayher/raw), which provided +access to Linux `AF_PACKET` sockets and *BSD equivalent mechanisms for sending +and receiving Ethernet frames. However, the *BSD support languished and I lack +the expertise and time to properly maintain code for operating systems I do not +use on a daily basis. + +Package `packet` is a successor to package `raw`, but exclusively focused on +Linux and `AF_PACKET` sockets. The APIs are nearly identical, but with a few +changes which take into account some of the lessons learned while working on +`raw`. + +Users are highly encouraged to migrate any existing Linux uses of `raw` to +package `packet` instead. This package will be supported for the foreseeable +future and will receive continued updates as necessary. diff --git a/vendor/github.com/mdlayher/packet/doc.go b/vendor/github.com/mdlayher/packet/doc.go new file mode 100644 index 000000000..4f555f038 --- /dev/null +++ b/vendor/github.com/mdlayher/packet/doc.go @@ -0,0 +1,2 @@ +// Package packet provides access to Linux packet sockets (AF_PACKET). +package packet diff --git a/vendor/github.com/mdlayher/packet/packet.go b/vendor/github.com/mdlayher/packet/packet.go new file mode 100644 index 000000000..a05117c78 --- /dev/null +++ b/vendor/github.com/mdlayher/packet/packet.go @@ -0,0 +1,241 @@ +package packet + +import ( + "net" + "syscall" + "time" + + "golang.org/x/net/bpf" +) + +const ( + // network is the network reported in net.OpError. + network = "packet" + + // Operation names which may be returned in net.OpError. + opClose = "close" + opGetsockopt = "getsockopt" + opListen = "listen" + opRawControl = "raw-control" + opRawRead = "raw-read" + opRawWrite = "raw-write" + opRead = "read" + opSet = "set" + opSetsockopt = "setsockopt" + opSyscallConn = "syscall-conn" + opWrite = "write" +) + +// Config contains options for a Conn. +type Config struct { + // Filter is an optional assembled BPF filter which can be applied to the + // Conn before bind(2) is called. + // + // The Conn.SetBPF method serves the same purpose once a Conn has already + // been opened, but setting Filter applies the BPF filter before the Conn is + // bound. This ensures that unexpected packets will not be captured before + // the Conn is opened. + Filter []bpf.RawInstruction +} + +// Type is a socket type used when creating a Conn with Listen. +//enumcheck:exhaustive +type Type int + +// Possible Type values. Note that the zero value is not valid: callers must +// always specify one of Raw or Datagram when calling Listen. +const ( + _ Type = iota + Raw + Datagram +) + +// Listen opens a packet sockets connection on the specified interface, using +// the given socket type and protocol values. +// +// The socket type must be one of the Type constants: Raw or Datagram. +// +// The Config specifies optional configuration for the Conn. A nil *Config +// applies the default configuration. +func Listen(ifi *net.Interface, socketType Type, protocol int, cfg *Config) (*Conn, error) { + l, err := listen(ifi, socketType, protocol, cfg) + if err != nil { + return nil, opError(opListen, err, &Addr{HardwareAddr: ifi.HardwareAddr}) + } + + return l, nil +} + +// TODO(mdlayher): we want to support FileConn for advanced use cases, but this +// library would also need a big endian protocol value and an interface index. +// For now we won't bother, but reconsider in the future. + +var ( + _ net.PacketConn = &Conn{} + _ syscall.Conn = &Conn{} + _ bpf.Setter = &Conn{} +) + +// A Conn is an Linux packet sockets (AF_PACKET) implementation of a +// net.PacketConn. +type Conn struct { + c *conn + + // Metadata about the local connection. + addr *Addr + ifIndex int + protocol uint16 +} + +// Close closes the connection. +func (c *Conn) Close() error { + return c.opError(opClose, c.c.Close()) +} + +// LocalAddr returns the local network address. The Addr returned is shared by +// all invocations of LocalAddr, so do not modify it. +func (c *Conn) LocalAddr() net.Addr { return c.addr } + +// ReadFrom implements the net.PacketConn ReadFrom method. +func (c *Conn) ReadFrom(b []byte) (int, net.Addr, error) { + return c.readFrom(b) +} + +// WriteTo implements the net.PacketConn WriteTo method. +func (c *Conn) WriteTo(b []byte, addr net.Addr) (int, error) { + return c.writeTo(b, addr) +} + +// SetDeadline implements the net.PacketConn SetDeadline method. +func (c *Conn) SetDeadline(t time.Time) error { + return c.opError(opSet, c.c.SetDeadline(t)) +} + +// SetReadDeadline implements the net.PacketConn SetReadDeadline method. +func (c *Conn) SetReadDeadline(t time.Time) error { + return c.opError(opSet, c.c.SetReadDeadline(t)) +} + +// SetWriteDeadline implements the net.PacketConn SetWriteDeadline method. +func (c *Conn) SetWriteDeadline(t time.Time) error { + return c.opError(opSet, c.c.SetWriteDeadline(t)) +} + +// SetBPF attaches an assembled BPF program to the Conn. +func (c *Conn) SetBPF(filter []bpf.RawInstruction) error { + return c.opError(opSetsockopt, c.c.SetBPF(filter)) +} + +// SetPromiscuous enables or disables promiscuous mode on the Conn, allowing it +// to receive traffic that is not addressed to the Conn's network interface. +func (c *Conn) SetPromiscuous(enable bool) error { + return c.setPromiscuous(enable) +} + +// Stats contains statistics about a Conn reported by the Linux kernel. +type Stats struct { + // The total number of packets received. + Packets uint32 + + // The number of packets dropped. + Drops uint32 + + // The total number of times that a receive queue is frozen. May be zero if + // the Linux kernel is not new enough to support TPACKET_V3 statistics. + FreezeQueueCount uint32 +} + +// Stats retrieves statistics about the Conn from the Linux kernel. +// +// Note that calling Stats will reset the kernel's internal counters for this +// Conn. If you want to maintain cumulative statistics by polling Stats over +// time, you must do so in your calling code. +func (c *Conn) Stats() (*Stats, error) { return c.stats() } + +// SyscallConn returns a raw network connection. This implements the +// syscall.Conn interface. +func (c *Conn) SyscallConn() (syscall.RawConn, error) { + rc, err := c.c.SyscallConn() + if err != nil { + return nil, c.opError(opSyscallConn, err) + } + + return &rawConn{ + rc: rc, + addr: c.addr, + }, nil +} + +// opError is a convenience for the function opError that also passes the local +// and remote addresses of the Conn. +func (c *Conn) opError(op string, err error) error { + return opError(op, err, c.addr) +} + +// TODO(mdlayher): see if we can port smarter net.OpError logic into +// socket.Conn's SyscallConn type to avoid the need for this wrapper. + +var _ syscall.RawConn = &rawConn{} + +// A rawConn is a syscall.RawConn that wraps an internal syscall.RawConn in order +// to produce net.OpError error values. +type rawConn struct { + rc syscall.RawConn + addr *Addr +} + +// Control implements the syscall.RawConn Control method. +func (rc *rawConn) Control(fn func(fd uintptr)) error { + return rc.opError(opRawControl, rc.rc.Control(fn)) +} + +// Control implements the syscall.RawConn Read method. +func (rc *rawConn) Read(fn func(fd uintptr) (done bool)) error { + return rc.opError(opRawRead, rc.rc.Read(fn)) +} + +// Control implements the syscall.RawConn Write method. +func (rc *rawConn) Write(fn func(fd uintptr) (done bool)) error { + return rc.opError(opRawWrite, rc.rc.Write(fn)) +} + +// opError is a convenience for the function opError that also passes the +// address of the rawConn. +func (rc *rawConn) opError(op string, err error) error { + return opError(op, err, rc.addr) +} + +var _ net.Addr = &Addr{} + +// TODO(mdlayher): expose sll_hatype and sll_pkttype on receive Addr only. + +// An Addr is a physical-layer address. +type Addr struct { + HardwareAddr net.HardwareAddr +} + +// Network returns the address's network name, "packet". +func (a *Addr) Network() string { return network } + +// String returns the string representation of an Addr. +func (a *Addr) String() string { + return a.HardwareAddr.String() +} + +// opError unpacks err if possible, producing a net.OpError with the input +// parameters in order to implement net.PacketConn. As a convenience, opError +// returns nil if the input error is nil. +func opError(op string, err error, local net.Addr) error { + if err == nil { + return nil + } + + // TODO(mdlayher): try to comply with net.PacketConn as best as we can; land + // a nettest.TestPacketConn API upstream. + return &net.OpError{ + Op: op, + Net: network, + Addr: local, + Err: err, + } +} diff --git a/vendor/github.com/mdlayher/packet/packet_linux.go b/vendor/github.com/mdlayher/packet/packet_linux.go new file mode 100644 index 000000000..919e39d51 --- /dev/null +++ b/vendor/github.com/mdlayher/packet/packet_linux.go @@ -0,0 +1,248 @@ +//go:build linux +// +build linux + +package packet + +import ( + "context" + "encoding/binary" + "errors" + "math" + "net" + "os" + + "github.com/josharian/native" + "github.com/mdlayher/socket" + "golang.org/x/sys/unix" +) + +// A conn is the net.PacketConn implementation for packet sockets. We can use +// socket.Conn directly on Linux to implement most of the necessary methods. +type conn = socket.Conn + +// readFrom implements the net.PacketConn ReadFrom method using recvfrom(2). +func (c *Conn) readFrom(b []byte) (int, net.Addr, error) { + // From net.PacketConn documentation: + // + // "[ReadFrom] returns the number of bytes read (0 <= n <= len(p)) and any + // error encountered. Callers should always process the n > 0 bytes returned + // before considering the error err." + // + // c.opError will return nil if no error, but either way we return all the + // information that we have. + n, sa, err := c.c.Recvfrom(context.Background(), b, 0) + return n, fromSockaddr(sa), c.opError(opRead, err) +} + +// writeTo implements the net.PacketConn WriteTo method. +func (c *Conn) writeTo(b []byte, addr net.Addr) (int, error) { + sa, err := c.toSockaddr("sendto", addr) + if err != nil { + return 0, c.opError(opWrite, err) + } + + // TODO(mdlayher): it's curious that unix.Sendto does not return the number + // of bytes actually sent. Fake it for now, but investigate upstream. + if err := c.c.Sendto(context.Background(), b, 0, sa); err != nil { + return 0, c.opError(opWrite, err) + } + + return len(b), nil +} + +// setPromiscuous wraps setsockopt(2) for the unix.PACKET_MR_PROMISC option. +func (c *Conn) setPromiscuous(enable bool) error { + mreq := unix.PacketMreq{ + Ifindex: int32(c.ifIndex), + Type: unix.PACKET_MR_PROMISC, + } + + membership := unix.PACKET_DROP_MEMBERSHIP + if enable { + membership = unix.PACKET_ADD_MEMBERSHIP + } + + return c.opError( + opSetsockopt, + c.c.SetsockoptPacketMreq(unix.SOL_PACKET, membership, &mreq), + ) +} + +// stats wraps getsockopt(2) for tpacket_stats* types. +func (c *Conn) stats() (*Stats, error) { + const ( + level = unix.SOL_PACKET + name = unix.PACKET_STATISTICS + ) + + // Try to fetch V3 statistics first, they contain more detailed information. + if stats, err := c.c.GetsockoptTpacketStatsV3(level, name); err == nil { + return &Stats{ + Packets: stats.Packets, + Drops: stats.Drops, + FreezeQueueCount: stats.Freeze_q_cnt, + }, nil + } + + // There was an error fetching v3 stats, try to fall back. + stats, err := c.c.GetsockoptTpacketStats(level, name) + if err != nil { + return nil, c.opError(opGetsockopt, err) + } + + return &Stats{ + Packets: stats.Packets, + Drops: stats.Drops, + // FreezeQueueCount is not present. + }, nil +} + +// listen is the entry point for Listen on Linux. +func listen(ifi *net.Interface, socketType Type, protocol int, cfg *Config) (*Conn, error) { + if cfg == nil { + // Default configuration. + cfg = &Config{} + } + + // Convert Type to the matching SOCK_* constant. + var typ int + switch socketType { + case Raw: + typ = unix.SOCK_RAW + case Datagram: + typ = unix.SOCK_DGRAM + default: + return nil, errors.New("packet: invalid Type value") + } + + // Protocol is intentionally zero in call to socket(2); we can set it on + // bind(2) instead. Package raw notes: "Do not specify a protocol to avoid + // capturing packets which to not match cfg.Filter." + c, err := socket.Socket(unix.AF_PACKET, typ, 0, network, nil) + if err != nil { + return nil, err + } + + conn, err := bind(c, ifi.Index, protocol, cfg) + if err != nil { + _ = c.Close() + return nil, err + } + + return conn, nil +} + +// bind binds the *socket.Conn to finalize *Conn setup. +func bind(c *socket.Conn, ifIndex, protocol int, cfg *Config) (*Conn, error) { + if len(cfg.Filter) > 0 { + // The caller wants to apply a BPF filter before bind(2). + if err := c.SetBPF(cfg.Filter); err != nil { + return nil, err + } + } + + // packet(7) says we sll_protocol must be in network byte order. + pnet, err := htons(protocol) + if err != nil { + return nil, err + } + + // TODO(mdlayher): investigate the possibility of sll_ifindex = 0 because we + // could bind to any interface. + err = c.Bind(&unix.SockaddrLinklayer{ + Protocol: pnet, + Ifindex: ifIndex, + }) + if err != nil { + return nil, err + } + + lsa, err := c.Getsockname() + if err != nil { + return nil, err + } + + // Parse the physical layer address; sll_halen tells us how many bytes of + // sll_addr we should treat as valid. + lsall := lsa.(*unix.SockaddrLinklayer) + addr := make(net.HardwareAddr, lsall.Halen) + copy(addr, lsall.Addr[:]) + + return &Conn{ + c: c, + + addr: &Addr{HardwareAddr: addr}, + ifIndex: ifIndex, + protocol: pnet, + }, nil +} + +// fromSockaddr converts an opaque unix.Sockaddr to *Addr. If sa is nil, it +// returns nil. It panics if sa is not of type *unix.SockaddrLinklayer. +func fromSockaddr(sa unix.Sockaddr) *Addr { + if sa == nil { + return nil + } + + sall := sa.(*unix.SockaddrLinklayer) + + return &Addr{ + // The syscall already allocated sa; just slice into it with the + // appropriate length and type conversion rather than making a copy. + HardwareAddr: net.HardwareAddr(sall.Addr[:sall.Halen]), + } +} + +// toSockaddr converts a net.Addr to an opaque unix.Sockaddr. It returns an +// error if the fields cannot be packed into a *unix.SockaddrLinklayer. +func (c *Conn) toSockaddr( + op string, + addr net.Addr, +) (unix.Sockaddr, error) { + // The typical error convention for net.Conn types is + // net.OpError(os.SyscallError(syscall.Errno)), so all calls here should + // return os.SyscallError(syscall.Errno) so the caller can apply the final + // net.OpError wrapper. + + // Ensure the correct Addr type. + a, ok := addr.(*Addr) + if !ok || a.HardwareAddr == nil { + return nil, os.NewSyscallError(op, unix.EINVAL) + } + + // Pack Addr and Conn metadata into the appropriate sockaddr fields. From + // packet(7): + // + // "When you send packets it is enough to specify sll_family, sll_addr, + // sll_halen, sll_ifindex, and sll_protocol. The other fields should be 0." + // + // sll_family is set on the conversion to unix.RawSockaddrLinklayer. + sa := unix.SockaddrLinklayer{ + Ifindex: c.ifIndex, + Protocol: c.protocol, + } + + // Ensure the input address does not exceed the amount of space available; + // for example an IPoIB address is 20 bytes. + if len(a.HardwareAddr) > len(sa.Addr) { + return nil, os.NewSyscallError(op, unix.EINVAL) + } + + sa.Halen = uint8(len(a.HardwareAddr)) + copy(sa.Addr[:], a.HardwareAddr) + + return &sa, nil +} + +// htons converts a short (uint16) from host-to-network byte order. +func htons(i int) (uint16, error) { + if i < 0 || i > math.MaxUint16 { + return 0, errors.New("packet: protocol value out of range") + } + + // Store as big endian, retrieve as native endian. + var b [2]byte + binary.BigEndian.PutUint16(b[:], uint16(i)) + + return native.Endian.Uint16(b[:]), nil +} diff --git a/vendor/github.com/mdlayher/packet/packet_others.go b/vendor/github.com/mdlayher/packet/packet_others.go new file mode 100644 index 000000000..54a8cc429 --- /dev/null +++ b/vendor/github.com/mdlayher/packet/packet_others.go @@ -0,0 +1,33 @@ +//go:build !linux +// +build !linux + +package packet + +import ( + "fmt" + "net" + "runtime" + "syscall" + "time" + + "golang.org/x/net/bpf" +) + +// errUnimplemented is returned by all functions on non-Linux platforms. +var errUnimplemented = fmt.Errorf("packet: not implemented on %s", runtime.GOOS) + +func listen(_ *net.Interface, _ Type, _ int, _ *Config) (*Conn, error) { return nil, errUnimplemented } + +func (*Conn) readFrom(_ []byte) (int, net.Addr, error) { return 0, nil, errUnimplemented } +func (*Conn) writeTo(_ []byte, _ net.Addr) (int, error) { return 0, errUnimplemented } +func (*Conn) setPromiscuous(_ bool) error { return errUnimplemented } +func (*Conn) stats() (*Stats, error) { return nil, errUnimplemented } + +type conn struct{} + +func (*conn) Close() error { return errUnimplemented } +func (*conn) SetDeadline(_ time.Time) error { return errUnimplemented } +func (*conn) SetReadDeadline(_ time.Time) error { return errUnimplemented } +func (*conn) SetWriteDeadline(_ time.Time) error { return errUnimplemented } +func (*conn) SetBPF(_ []bpf.RawInstruction) error { return errUnimplemented } +func (*conn) SyscallConn() (syscall.RawConn, error) { return nil, errUnimplemented } diff --git a/vendor/github.com/mdlayher/socket/CHANGELOG.md b/vendor/github.com/mdlayher/socket/CHANGELOG.md new file mode 100644 index 000000000..b83418532 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/CHANGELOG.md @@ -0,0 +1,94 @@ +# CHANGELOG + +## v0.5.1 + +- [Improvement]: revert `go.mod` to Go 1.20 to [resolve an issue around Go + module version upgrades](https://github.com/mdlayher/socket/issues/13). + +## v0.5.0 + +**This is the first release of package socket that only supports Go 1.21+. +Users on older versions of Go must use v0.4.1.** + +- [Improvement]: drop support for older versions of Go. +- [New API]: add `socket.Conn` wrappers for various `Getsockopt` and + `Setsockopt` system calls. + +## v0.4.1 + +- [Bug Fix] [commit](https://github.com/mdlayher/socket/commit/2a14ceef4da279de1f957c5761fffcc6c87bbd3b): + ensure `socket.Conn` can be used with non-socket file descriptors by handling + `ENOTSOCK` in the constructor. + +## v0.4.0 + +**This is the first release of package socket that only supports Go 1.18+. +Users on older versions of Go must use v0.3.0.** + +- [Improvement]: drop support for older versions of Go so we can begin using + modern versions of `x/sys` and other dependencies. + +## v0.3.0 + +**This is the last release of package socket that supports Go 1.17 and below.** + +- [New API/API change] [PR](https://github.com/mdlayher/socket/pull/8): + numerous `socket.Conn` methods now support context cancelation. Future + releases will continue adding support as needed. + - New `ReadContext` and `WriteContext` methods. + - `Connect`, `Recvfrom`, `Recvmsg`, `Sendmsg`, and `Sendto` methods now accept + a context. + - `Sendto` parameter order was also fixed to match the underlying syscall. + +## v0.2.3 + +- [New API] [commit](https://github.com/mdlayher/socket/commit/a425d96e0f772c053164f8ce4c9c825380a98086): + `socket.Conn` has new `Pidfd*` methods for wrapping the `pidfd_*(2)` family of + system calls. + +## v0.2.2 + +- [New API] [commit](https://github.com/mdlayher/socket/commit/a2429f1dfe8ec2586df5a09f50ead865276cd027): + `socket.Conn` has new `IoctlKCM*` methods for wrapping `ioctl(2)` for `AF_KCM` + operations. + +## v0.2.1 + +- [New API] [commit](https://github.com/mdlayher/socket/commit/b18ddbe9caa0e34552b4409a3aa311cb460d2f99): + `socket.Conn` has a new `SetsockoptPacketMreq` method for wrapping + `setsockopt(2)` for `AF_PACKET` socket options. + +## v0.2.0 + +- [New API] [commit](https://github.com/mdlayher/socket/commit/6e912a68523c45e5fd899239f4b46c402dd856da): + `socket.FileConn` can be used to create a `socket.Conn` from an existing + `os.File`, which may be provided by systemd socket activation or another + external mechanism. +- [API change] [commit](https://github.com/mdlayher/socket/commit/66d61f565188c23fe02b24099ddc856d538bf1a7): + `socket.Conn.Connect` now returns the `unix.Sockaddr` value provided by + `getpeername(2)`, since we have to invoke that system call anyway to verify + that a connection to a remote peer was successfully established. +- [Bug Fix] [commit](https://github.com/mdlayher/socket/commit/b60b2dbe0ac3caff2338446a150083bde8c5c19c): + check the correct error from `unix.GetsockoptInt` in the `socket.Conn.Connect` + method. Thanks @vcabbage! + +## v0.1.2 + +- [Bug Fix]: `socket.Conn.Connect` now properly checks the `SO_ERROR` socket + option value after calling `connect(2)` to verify whether or not a connection + could successfully be established. This means that `Connect` should now report + an error for an `AF_INET` TCP connection refused or `AF_VSOCK` connection + reset by peer. +- [New API]: add `socket.Conn.Getpeername` for use in `Connect`, but also for + use by external callers. + +## v0.1.1 + +- [New API]: `socket.Conn` now has `CloseRead`, `CloseWrite`, and `Shutdown` + methods. +- [Improvement]: internal rework to more robustly handle various errors. + +## v0.1.0 + +- Initial unstable release. Most functionality has been developed and ported +from package [`netlink`](https://github.com/mdlayher/netlink). diff --git a/vendor/github.com/mdlayher/socket/LICENSE.md b/vendor/github.com/mdlayher/socket/LICENSE.md new file mode 100644 index 000000000..3ccdb75b2 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/LICENSE.md @@ -0,0 +1,9 @@ +# MIT License + +Copyright (C) 2021 Matt Layher + +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: + +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. diff --git a/vendor/github.com/mdlayher/socket/README.md b/vendor/github.com/mdlayher/socket/README.md new file mode 100644 index 000000000..2aa065cbb --- /dev/null +++ b/vendor/github.com/mdlayher/socket/README.md @@ -0,0 +1,23 @@ +# socket [![Test Status](https://github.com/mdlayher/socket/workflows/Test/badge.svg)](https://github.com/mdlayher/socket/actions) [![Go Reference](https://pkg.go.dev/badge/github.com/mdlayher/socket.svg)](https://pkg.go.dev/github.com/mdlayher/socket) [![Go Report Card](https://goreportcard.com/badge/github.com/mdlayher/socket)](https://goreportcard.com/report/github.com/mdlayher/socket) + +Package `socket` provides a low-level network connection type which integrates +with Go's runtime network poller to provide asynchronous I/O and deadline +support. MIT Licensed. + +This package focuses on UNIX-like operating systems which make use of BSD +sockets system call APIs. It is meant to be used as a foundation for the +creation of operating system-specific socket packages, for socket families such +as Linux's `AF_NETLINK`, `AF_PACKET`, or `AF_VSOCK`. This package should not be +used directly in end user applications. + +Any use of package socket should be guarded by build tags, as one would also +use when importing the `syscall` or `golang.org/x/sys` packages. + +## Stability + +See the [CHANGELOG](./CHANGELOG.md) file for a description of changes between +releases. + +This package only supports the two most recent major versions of Go, mirroring +Go's own release policy. Older versions of Go may lack critical features and bug +fixes which are necessary for this package to function correctly. diff --git a/vendor/github.com/mdlayher/socket/accept.go b/vendor/github.com/mdlayher/socket/accept.go new file mode 100644 index 000000000..47e9d897e --- /dev/null +++ b/vendor/github.com/mdlayher/socket/accept.go @@ -0,0 +1,23 @@ +//go:build !dragonfly && !freebsd && !illumos && !linux +// +build !dragonfly,!freebsd,!illumos,!linux + +package socket + +import ( + "fmt" + "runtime" + + "golang.org/x/sys/unix" +) + +const sysAccept = "accept" + +// accept wraps accept(2). +func accept(fd, flags int) (int, unix.Sockaddr, error) { + if flags != 0 { + // These operating systems have no support for flags to accept(2). + return 0, nil, fmt.Errorf("socket: Conn.Accept flags are ineffective on %s", runtime.GOOS) + } + + return unix.Accept(fd) +} diff --git a/vendor/github.com/mdlayher/socket/accept4.go b/vendor/github.com/mdlayher/socket/accept4.go new file mode 100644 index 000000000..e1016b206 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/accept4.go @@ -0,0 +1,15 @@ +//go:build dragonfly || freebsd || illumos || linux +// +build dragonfly freebsd illumos linux + +package socket + +import ( + "golang.org/x/sys/unix" +) + +const sysAccept = "accept4" + +// accept wraps accept4(2). +func accept(fd, flags int) (int, unix.Sockaddr, error) { + return unix.Accept4(fd, flags) +} diff --git a/vendor/github.com/mdlayher/socket/conn.go b/vendor/github.com/mdlayher/socket/conn.go new file mode 100644 index 000000000..5be502f5a --- /dev/null +++ b/vendor/github.com/mdlayher/socket/conn.go @@ -0,0 +1,894 @@ +package socket + +import ( + "context" + "errors" + "io" + "os" + "sync" + "sync/atomic" + "syscall" + "time" + + "golang.org/x/sys/unix" +) + +// Lock in an expected public interface for convenience. +var _ interface { + io.ReadWriteCloser + syscall.Conn + SetDeadline(t time.Time) error + SetReadDeadline(t time.Time) error + SetWriteDeadline(t time.Time) error +} = &Conn{} + +// A Conn is a low-level network connection which integrates with Go's runtime +// network poller to provide asynchronous I/O and deadline support. +// +// Many of a Conn's blocking methods support net.Conn deadlines as well as +// cancelation via context. Note that passing a context with a deadline set will +// override any of the previous deadlines set by calls to the SetDeadline family +// of methods. +type Conn struct { + // Indicates whether or not Conn.Close has been called. Must be accessed + // atomically. Atomics definitions must come first in the Conn struct. + closed uint32 + + // A unique name for the Conn which is also associated with derived file + // descriptors such as those created by accept(2). + name string + + // facts contains information we have determined about Conn to trigger + // alternate behavior in certain functions. + facts facts + + // Provides access to the underlying file registered with the runtime + // network poller, and arbitrary raw I/O calls. + fd *os.File + rc syscall.RawConn +} + +// facts contains facts about a Conn. +type facts struct { + // isStream reports whether this is a streaming descriptor, as opposed to a + // packet-based descriptor like a UDP socket. + isStream bool + + // zeroReadIsEOF reports Whether a zero byte read indicates EOF. This is + // false for a message based socket connection. + zeroReadIsEOF bool +} + +// A Config contains options for a Conn. +type Config struct { + // NetNS specifies the Linux network namespace the Conn will operate in. + // This option is unsupported on other operating systems. + // + // If set (non-zero), Conn will enter the specified network namespace and an + // error will occur in Socket if the operation fails. + // + // If not set (zero), a best-effort attempt will be made to enter the + // network namespace of the calling thread: this means that any changes made + // to the calling thread's network namespace will also be reflected in Conn. + // If this operation fails (due to lack of permissions or because network + // namespaces are disabled by kernel configuration), Socket will not return + // an error, and the Conn will operate in the default network namespace of + // the process. This enables non-privileged use of Conn in applications + // which do not require elevated privileges. + // + // Entering a network namespace is a privileged operation (root or + // CAP_SYS_ADMIN are required), and most applications should leave this set + // to 0. + NetNS int +} + +// High-level methods which provide convenience over raw system calls. + +// Close closes the underlying file descriptor for the Conn, which also causes +// all in-flight I/O operations to immediately unblock and return errors. Any +// subsequent uses of Conn will result in EBADF. +func (c *Conn) Close() error { + // The caller has expressed an intent to close the socket, so immediately + // increment s.closed to force further calls to result in EBADF before also + // closing the file descriptor to unblock any outstanding operations. + // + // Because other operations simply check for s.closed != 0, we will permit + // double Close, which would increment s.closed beyond 1. + if atomic.AddUint32(&c.closed, 1) != 1 { + // Multiple Close calls. + return nil + } + + return os.NewSyscallError("close", c.fd.Close()) +} + +// CloseRead shuts down the reading side of the Conn. Most callers should just +// use Close. +func (c *Conn) CloseRead() error { return c.Shutdown(unix.SHUT_RD) } + +// CloseWrite shuts down the writing side of the Conn. Most callers should just +// use Close. +func (c *Conn) CloseWrite() error { return c.Shutdown(unix.SHUT_WR) } + +// Read reads directly from the underlying file descriptor. +func (c *Conn) Read(b []byte) (int, error) { return c.fd.Read(b) } + +// ReadContext reads from the underlying file descriptor with added support for +// context cancelation. +func (c *Conn) ReadContext(ctx context.Context, b []byte) (int, error) { + if c.facts.isStream && len(b) > maxRW { + b = b[:maxRW] + } + + n, err := readT(c, ctx, "read", func(fd int) (int, error) { + return unix.Read(fd, b) + }) + if n == 0 && err == nil && c.facts.zeroReadIsEOF { + return 0, io.EOF + } + + return n, os.NewSyscallError("read", err) +} + +// Write writes directly to the underlying file descriptor. +func (c *Conn) Write(b []byte) (int, error) { return c.fd.Write(b) } + +// WriteContext writes to the underlying file descriptor with added support for +// context cancelation. +func (c *Conn) WriteContext(ctx context.Context, b []byte) (int, error) { + var ( + n, nn int + err error + ) + + doErr := c.write(ctx, "write", func(fd int) error { + max := len(b) + if c.facts.isStream && max-nn > maxRW { + max = nn + maxRW + } + + n, err = unix.Write(fd, b[nn:max]) + if n > 0 { + nn += n + } + if nn == len(b) { + return err + } + if n == 0 && err == nil { + err = io.ErrUnexpectedEOF + return nil + } + + return err + }) + if doErr != nil { + return 0, doErr + } + + return nn, os.NewSyscallError("write", err) +} + +// SetDeadline sets both the read and write deadlines associated with the Conn. +func (c *Conn) SetDeadline(t time.Time) error { return c.fd.SetDeadline(t) } + +// SetReadDeadline sets the read deadline associated with the Conn. +func (c *Conn) SetReadDeadline(t time.Time) error { return c.fd.SetReadDeadline(t) } + +// SetWriteDeadline sets the write deadline associated with the Conn. +func (c *Conn) SetWriteDeadline(t time.Time) error { return c.fd.SetWriteDeadline(t) } + +// ReadBuffer gets the size of the operating system's receive buffer associated +// with the Conn. +func (c *Conn) ReadBuffer() (int, error) { + return c.GetsockoptInt(unix.SOL_SOCKET, unix.SO_RCVBUF) +} + +// WriteBuffer gets the size of the operating system's transmit buffer +// associated with the Conn. +func (c *Conn) WriteBuffer() (int, error) { + return c.GetsockoptInt(unix.SOL_SOCKET, unix.SO_SNDBUF) +} + +// SetReadBuffer sets the size of the operating system's receive buffer +// associated with the Conn. +// +// When called with elevated privileges on Linux, the SO_RCVBUFFORCE option will +// be used to override operating system limits. Otherwise SO_RCVBUF is used +// (which obeys operating system limits). +func (c *Conn) SetReadBuffer(bytes int) error { return c.setReadBuffer(bytes) } + +// SetWriteBuffer sets the size of the operating system's transmit buffer +// associated with the Conn. +// +// When called with elevated privileges on Linux, the SO_SNDBUFFORCE option will +// be used to override operating system limits. Otherwise SO_SNDBUF is used +// (which obeys operating system limits). +func (c *Conn) SetWriteBuffer(bytes int) error { return c.setWriteBuffer(bytes) } + +// SyscallConn returns a raw network connection. This implements the +// syscall.Conn interface. +// +// SyscallConn is intended for advanced use cases, such as getting and setting +// arbitrary socket options using the socket's file descriptor. If possible, +// those operations should be performed using methods on Conn instead. +// +// Once invoked, it is the caller's responsibility to ensure that operations +// performed using Conn and the syscall.RawConn do not conflict with each other. +func (c *Conn) SyscallConn() (syscall.RawConn, error) { + if atomic.LoadUint32(&c.closed) != 0 { + return nil, os.NewSyscallError("syscallconn", unix.EBADF) + } + + // TODO(mdlayher): mutex or similar to enforce syscall.RawConn contract of + // FD remaining valid for duration of calls? + return c.rc, nil +} + +// Socket wraps the socket(2) system call to produce a Conn. domain, typ, and +// proto are passed directly to socket(2), and name should be a unique name for +// the socket type such as "netlink" or "vsock". +// +// The cfg parameter specifies optional configuration for the Conn. If nil, no +// additional configuration will be applied. +// +// If the operating system supports SOCK_CLOEXEC and SOCK_NONBLOCK, they are +// automatically applied to typ to mirror the standard library's socket flag +// behaviors. +func Socket(domain, typ, proto int, name string, cfg *Config) (*Conn, error) { + if cfg == nil { + cfg = &Config{} + } + + if cfg.NetNS == 0 { + // Non-Linux or no network namespace. + return socket(domain, typ, proto, name) + } + + // Linux only: create Conn in the specified network namespace. + return withNetNS(cfg.NetNS, func() (*Conn, error) { + return socket(domain, typ, proto, name) + }) +} + +// socket is the internal, cross-platform entry point for socket(2). +func socket(domain, typ, proto int, name string) (*Conn, error) { + var ( + fd int + err error + ) + + for { + fd, err = unix.Socket(domain, typ|socketFlags, proto) + switch { + case err == nil: + // Some OSes already set CLOEXEC with typ. + if !flagCLOEXEC { + unix.CloseOnExec(fd) + } + + // No error, prepare the Conn. + return New(fd, name) + case !ready(err): + // System call interrupted or not ready, try again. + continue + case err == unix.EINVAL, err == unix.EPROTONOSUPPORT: + // On Linux, SOCK_NONBLOCK and SOCK_CLOEXEC were introduced in + // 2.6.27. On FreeBSD, both flags were introduced in FreeBSD 10. + // EINVAL and EPROTONOSUPPORT check for earlier versions of these + // OSes respectively. + // + // Mirror what the standard library does when creating file + // descriptors: avoid racing a fork/exec with the creation of new + // file descriptors, so that child processes do not inherit socket + // file descriptors unexpectedly. + // + // For a more thorough explanation, see similar work in the Go tree: + // func sysSocket in net/sock_cloexec.go, as well as the detailed + // comment in syscall/exec_unix.go. + syscall.ForkLock.RLock() + fd, err = unix.Socket(domain, typ, proto) + if err != nil { + syscall.ForkLock.RUnlock() + return nil, os.NewSyscallError("socket", err) + } + unix.CloseOnExec(fd) + syscall.ForkLock.RUnlock() + + return New(fd, name) + default: + // Unhandled error. + return nil, os.NewSyscallError("socket", err) + } + } +} + +// FileConn returns a copy of the network connection corresponding to the open +// file. It is the caller's responsibility to close the file when finished. +// Closing the Conn does not affect the File, and closing the File does not +// affect the Conn. +func FileConn(f *os.File, name string) (*Conn, error) { + // First we'll try to do fctnl(2) with F_DUPFD_CLOEXEC because we can dup + // the file descriptor and set the flag in one syscall. + fd, err := unix.FcntlInt(f.Fd(), unix.F_DUPFD_CLOEXEC, 0) + switch err { + case nil: + // OK, ready to set up non-blocking I/O. + return New(fd, name) + case unix.EINVAL: + // The kernel rejected our fcntl(2), fall back to separate dup(2) and + // setting close on exec. + // + // Mirror what the standard library does when creating file descriptors: + // avoid racing a fork/exec with the creation of new file descriptors, + // so that child processes do not inherit socket file descriptors + // unexpectedly. + syscall.ForkLock.RLock() + fd, err := unix.Dup(fd) + if err != nil { + syscall.ForkLock.RUnlock() + return nil, os.NewSyscallError("dup", err) + } + unix.CloseOnExec(fd) + syscall.ForkLock.RUnlock() + + return New(fd, name) + default: + // Any other errors. + return nil, os.NewSyscallError("fcntl", err) + } +} + +// New wraps an existing file descriptor to create a Conn. name should be a +// unique name for the socket type such as "netlink" or "vsock". +// +// Most callers should use Socket or FileConn to construct a Conn. New is +// intended for integrating with specific system calls which provide a file +// descriptor that supports asynchronous I/O. The file descriptor is immediately +// set to nonblocking mode and registered with Go's runtime network poller for +// future I/O operations. +// +// Unlike FileConn, New does not duplicate the existing file descriptor in any +// way. The returned Conn takes ownership of the underlying file descriptor. +func New(fd int, name string) (*Conn, error) { + // All Conn I/O is nonblocking for integration with Go's runtime network + // poller. Depending on the OS this might already be set but it can't hurt + // to set it again. + if err := unix.SetNonblock(fd, true); err != nil { + return nil, os.NewSyscallError("setnonblock", err) + } + + // os.NewFile registers the non-blocking file descriptor with the runtime + // poller, which is then used for most subsequent operations except those + // that require raw I/O via SyscallConn. + // + // See also: https://golang.org/pkg/os/#NewFile + f := os.NewFile(uintptr(fd), name) + rc, err := f.SyscallConn() + if err != nil { + return nil, err + } + + c := &Conn{ + name: name, + fd: f, + rc: rc, + } + + // Probe the file descriptor for socket settings. + sotype, err := c.GetsockoptInt(unix.SOL_SOCKET, unix.SO_TYPE) + switch { + case err == nil: + // File is a socket, check its properties. + c.facts = facts{ + isStream: sotype == unix.SOCK_STREAM, + zeroReadIsEOF: sotype != unix.SOCK_DGRAM && sotype != unix.SOCK_RAW, + } + case errors.Is(err, unix.ENOTSOCK): + // File is not a socket, treat it as a regular file. + c.facts = facts{ + isStream: true, + zeroReadIsEOF: true, + } + default: + return nil, err + } + + return c, nil +} + +// Low-level methods which provide raw system call access. + +// Accept wraps accept(2) or accept4(2) depending on the operating system, but +// returns a Conn for the accepted connection rather than a raw file descriptor. +// +// If the operating system supports accept4(2) (which allows flags), +// SOCK_CLOEXEC and SOCK_NONBLOCK are automatically applied to flags to mirror +// the standard library's socket flag behaviors. +// +// If the operating system only supports accept(2) (which does not allow flags) +// and flags is not zero, an error will be returned. +// +// Accept obeys context cancelation and uses the deadline set on the context to +// cancel accepting the next connection. If a deadline is set on ctx, this +// deadline will override any previous deadlines set using SetDeadline or +// SetReadDeadline. Upon return, the read deadline is cleared. +func (c *Conn) Accept(ctx context.Context, flags int) (*Conn, unix.Sockaddr, error) { + type ret struct { + nfd int + sa unix.Sockaddr + } + + r, err := readT(c, ctx, sysAccept, func(fd int) (ret, error) { + // Either accept(2) or accept4(2) depending on the OS. + nfd, sa, err := accept(fd, flags|socketFlags) + return ret{nfd, sa}, err + }) + if err != nil { + // internal/poll, context error, or user function error. + return nil, nil, err + } + + // Successfully accepted a connection, wrap it in a Conn for use by the + // caller. + ac, err := New(r.nfd, c.name) + if err != nil { + return nil, nil, err + } + + return ac, r.sa, nil +} + +// Bind wraps bind(2). +func (c *Conn) Bind(sa unix.Sockaddr) error { + return c.control("bind", func(fd int) error { return unix.Bind(fd, sa) }) +} + +// Connect wraps connect(2). In order to verify that the underlying socket is +// connected to a remote peer, Connect calls getpeername(2) and returns the +// unix.Sockaddr from that call. +// +// Connect obeys context cancelation and uses the deadline set on the context to +// cancel connecting to a remote peer. If a deadline is set on ctx, this +// deadline will override any previous deadlines set using SetDeadline or +// SetWriteDeadline. Upon return, the write deadline is cleared. +func (c *Conn) Connect(ctx context.Context, sa unix.Sockaddr) (unix.Sockaddr, error) { + const op = "connect" + + // TODO(mdlayher): it would seem that trying to connect to unbound vsock + // listeners by calling Connect multiple times results in ECONNRESET for the + // first and nil error for subsequent calls. Do we need to memoize the + // error? Check what the stdlib behavior is. + + var ( + // Track progress between invocations of the write closure. We don't + // have an explicit WaitWrite call like internal/poll does, so we have + // to wait until the runtime calls the closure again to indicate we can + // write. + progress uint32 + + // Capture closure sockaddr and error. + rsa unix.Sockaddr + err error + ) + + doErr := c.write(ctx, op, func(fd int) error { + if atomic.AddUint32(&progress, 1) == 1 { + // First call: initiate connect. + return unix.Connect(fd, sa) + } + + // Subsequent calls: the runtime network poller indicates fd is + // writable. Check for errno. + errno, gerr := c.GetsockoptInt(unix.SOL_SOCKET, unix.SO_ERROR) + if gerr != nil { + return gerr + } + if errno != 0 { + // Connection is still not ready or failed. If errno indicates + // the socket is not ready, we will wait for the next write + // event. Otherwise we propagate this errno back to the as a + // permanent error. + uerr := unix.Errno(errno) + err = uerr + return uerr + } + + // According to internal/poll, it's possible for the runtime network + // poller to spuriously wake us and return errno 0 for SO_ERROR. + // Make sure we are actually connected to a peer. + peer, err := c.Getpeername() + if err != nil { + // internal/poll unconditionally goes back to WaitWrite. + // Synthesize an error that will do the same for us. + return unix.EAGAIN + } + + // Connection complete. + rsa = peer + return nil + }) + if doErr != nil { + // internal/poll or context error. + return nil, doErr + } + + if err == unix.EISCONN { + // TODO(mdlayher): is this block obsolete with the addition of the + // getsockopt SO_ERROR check above? + // + // EISCONN is reported if the socket is already established and should + // not be treated as an error. + // - Darwin reports this for at least TCP sockets + // - Linux reports this for at least AF_VSOCK sockets + return rsa, nil + } + + return rsa, os.NewSyscallError(op, err) +} + +// Getsockname wraps getsockname(2). +func (c *Conn) Getsockname() (unix.Sockaddr, error) { + return controlT(c, "getsockname", unix.Getsockname) +} + +// Getpeername wraps getpeername(2). +func (c *Conn) Getpeername() (unix.Sockaddr, error) { + return controlT(c, "getpeername", unix.Getpeername) +} + +// GetsockoptICMPv6Filter wraps getsockopt(2) for *unix.ICMPv6Filter values. +func (c *Conn) GetsockoptICMPv6Filter(level, opt int) (*unix.ICMPv6Filter, error) { + return controlT(c, "getsockopt", func(fd int) (*unix.ICMPv6Filter, error) { + return unix.GetsockoptICMPv6Filter(fd, level, opt) + }) +} + +// GetsockoptInt wraps getsockopt(2) for integer values. +func (c *Conn) GetsockoptInt(level, opt int) (int, error) { + return controlT(c, "getsockopt", func(fd int) (int, error) { + return unix.GetsockoptInt(fd, level, opt) + }) +} + +// GetsockoptString wraps getsockopt(2) for string values. +func (c *Conn) GetsockoptString(level, opt int) (string, error) { + return controlT(c, "getsockopt", func(fd int) (string, error) { + return unix.GetsockoptString(fd, level, opt) + }) +} + +// Listen wraps listen(2). +func (c *Conn) Listen(n int) error { + return c.control("listen", func(fd int) error { return unix.Listen(fd, n) }) +} + +// Recvmsg wraps recvmsg(2). +func (c *Conn) Recvmsg(ctx context.Context, p, oob []byte, flags int) (int, int, int, unix.Sockaddr, error) { + type ret struct { + n, oobn, recvflags int + from unix.Sockaddr + } + + r, err := readT(c, ctx, "recvmsg", func(fd int) (ret, error) { + n, oobn, recvflags, from, err := unix.Recvmsg(fd, p, oob, flags) + return ret{n, oobn, recvflags, from}, err + }) + if r.n == 0 && err == nil && c.facts.zeroReadIsEOF { + return 0, 0, 0, nil, io.EOF + } + + return r.n, r.oobn, r.recvflags, r.from, err +} + +// Recvfrom wraps recvfrom(2). +func (c *Conn) Recvfrom(ctx context.Context, p []byte, flags int) (int, unix.Sockaddr, error) { + type ret struct { + n int + addr unix.Sockaddr + } + + out, err := readT(c, ctx, "recvfrom", func(fd int) (ret, error) { + n, addr, err := unix.Recvfrom(fd, p, flags) + return ret{n, addr}, err + }) + if out.n == 0 && err == nil && c.facts.zeroReadIsEOF { + return 0, nil, io.EOF + } + + return out.n, out.addr, err +} + +// Sendmsg wraps sendmsg(2). +func (c *Conn) Sendmsg(ctx context.Context, p, oob []byte, to unix.Sockaddr, flags int) (int, error) { + return writeT(c, ctx, "sendmsg", func(fd int) (int, error) { + return unix.SendmsgN(fd, p, oob, to, flags) + }) +} + +// Sendto wraps sendto(2). +func (c *Conn) Sendto(ctx context.Context, p []byte, flags int, to unix.Sockaddr) error { + return c.write(ctx, "sendto", func(fd int) error { + return unix.Sendto(fd, p, flags, to) + }) +} + +// SetsockoptICMPv6Filter wraps setsockopt(2) for *unix.ICMPv6Filter values. +func (c *Conn) SetsockoptICMPv6Filter(level, opt int, filter *unix.ICMPv6Filter) error { + return c.control("setsockopt", func(fd int) error { + return unix.SetsockoptICMPv6Filter(fd, level, opt, filter) + }) +} + +// SetsockoptInt wraps setsockopt(2) for integer values. +func (c *Conn) SetsockoptInt(level, opt, value int) error { + return c.control("setsockopt", func(fd int) error { + return unix.SetsockoptInt(fd, level, opt, value) + }) +} + +// SetsockoptString wraps setsockopt(2) for string values. +func (c *Conn) SetsockoptString(level, opt int, value string) error { + return c.control("setsockopt", func(fd int) error { + return unix.SetsockoptString(fd, level, opt, value) + }) +} + +// Shutdown wraps shutdown(2). +func (c *Conn) Shutdown(how int) error { + return c.control("shutdown", func(fd int) error { return unix.Shutdown(fd, how) }) +} + +// Conn low-level read/write/control functions. These functions mirror the +// syscall.RawConn APIs but the input closures return errors rather than +// booleans. + +// read wraps readT to execute a function and capture its error result. This is +// a convenience wrapper for functions which don't return any extra values. +func (c *Conn) read(ctx context.Context, op string, f func(fd int) error) error { + _, err := readT(c, ctx, op, func(fd int) (struct{}, error) { + return struct{}{}, f(fd) + }) + return err +} + +// write executes f, a write function, against the associated file descriptor. +// op is used to create an *os.SyscallError if the file descriptor is closed. +func (c *Conn) write(ctx context.Context, op string, f func(fd int) error) error { + _, err := writeT(c, ctx, op, func(fd int) (struct{}, error) { + return struct{}{}, f(fd) + }) + return err +} + +// readT executes c.rc.Read for op using the input function, returning a newly +// allocated result T. +func readT[T any](c *Conn, ctx context.Context, op string, f func(fd int) (T, error)) (T, error) { + return rwT(c, rwContext[T]{ + Context: ctx, + Type: read, + Op: op, + Do: f, + }) +} + +// writeT executes c.rc.Write for op using the input function, returning a newly +// allocated result T. +func writeT[T any](c *Conn, ctx context.Context, op string, f func(fd int) (T, error)) (T, error) { + return rwT(c, rwContext[T]{ + Context: ctx, + Type: write, + Op: op, + Do: f, + }) +} + +// readWrite indicates if an operation intends to read or write. +type readWrite bool + +// Possible readWrite values. +const ( + read readWrite = false + write readWrite = true +) + +// An rwContext provides arguments to rwT. +type rwContext[T any] struct { + // The caller's context passed for cancelation. + Context context.Context + + // The type of an operation: read or write. + Type readWrite + + // The name of the operation used in errors. + Op string + + // The actual function to perform. + Do func(fd int) (T, error) +} + +// rwT executes c.rc.Read or c.rc.Write (depending on the value of rw.Type) for +// rw.Op using the input function, returning a newly allocated result T. +// +// It obeys context cancelation and the rw.Context must not be nil. +func rwT[T any](c *Conn, rw rwContext[T]) (T, error) { + if atomic.LoadUint32(&c.closed) != 0 { + // If the file descriptor is already closed, do nothing. + return *new(T), os.NewSyscallError(rw.Op, unix.EBADF) + } + + if err := rw.Context.Err(); err != nil { + // Early exit due to context cancel. + return *new(T), os.NewSyscallError(rw.Op, err) + } + + var ( + // The read or write function used to access the runtime network poller. + poll func(func(uintptr) bool) error + + // The read or write function used to set the matching deadline. + deadline func(time.Time) error + ) + + if rw.Type == write { + poll = c.rc.Write + deadline = c.SetWriteDeadline + } else { + poll = c.rc.Read + deadline = c.SetReadDeadline + } + + var ( + // Whether or not the context carried a deadline we are actively using + // for cancelation. + setDeadline bool + + // Signals for the cancelation watcher goroutine. + wg sync.WaitGroup + doneC = make(chan struct{}) + + // Atomic: reports whether we have to disarm the deadline. + needDisarm atomic.Bool + ) + + // On cancel, clean up the watcher. + defer func() { + close(doneC) + wg.Wait() + }() + + if d, ok := rw.Context.Deadline(); ok { + // The context has an explicit deadline. We will use it for cancelation + // but disarm it after poll for the next call. + if err := deadline(d); err != nil { + return *new(T), err + } + setDeadline = true + needDisarm.Store(true) + } else { + // The context does not have an explicit deadline. We have to watch for + // cancelation so we can propagate that signal to immediately unblock + // the runtime network poller. + // + // TODO(mdlayher): is it possible to detect a background context vs a + // context with possible future cancel? + wg.Add(1) + go func() { + defer wg.Done() + + select { + case <-rw.Context.Done(): + // Cancel the operation. Make the caller disarm after poll + // returns. + needDisarm.Store(true) + _ = deadline(time.Unix(0, 1)) + case <-doneC: + // Nothing to do. + } + }() + } + + var ( + t T + err error + ) + + pollErr := poll(func(fd uintptr) bool { + t, err = rw.Do(int(fd)) + return ready(err) + }) + + if needDisarm.Load() { + _ = deadline(time.Time{}) + } + + if pollErr != nil { + if rw.Context.Err() != nil || (setDeadline && errors.Is(pollErr, os.ErrDeadlineExceeded)) { + // The caller canceled the operation or we set a deadline internally + // and it was reached. + // + // Unpack a plain context error. We wait for the context to be done + // to synchronize state externally. Otherwise we have noticed I/O + // timeout wakeups when we set a deadline but the context was not + // yet marked done. + <-rw.Context.Done() + return *new(T), os.NewSyscallError(rw.Op, rw.Context.Err()) + } + + // Error from syscall.RawConn methods. Conventionally the standard + // library does not wrap internal/poll errors in os.NewSyscallError. + return *new(T), pollErr + } + + // Result from user function. + return t, os.NewSyscallError(rw.Op, err) +} + +// control executes Conn.control for op using the input function. +func (c *Conn) control(op string, f func(fd int) error) error { + _, err := controlT(c, op, func(fd int) (struct{}, error) { + return struct{}{}, f(fd) + }) + return err +} + +// controlT executes c.rc.Control for op using the input function, returning a +// newly allocated result T. +func controlT[T any](c *Conn, op string, f func(fd int) (T, error)) (T, error) { + if atomic.LoadUint32(&c.closed) != 0 { + // If the file descriptor is already closed, do nothing. + return *new(T), os.NewSyscallError(op, unix.EBADF) + } + + var ( + t T + err error + ) + + doErr := c.rc.Control(func(fd uintptr) { + // Repeatedly attempt the syscall(s) invoked by f until completion is + // indicated by the return value of ready or the context is canceled. + // + // The last values for t and err are captured outside of the closure for + // use when the loop breaks. + for { + t, err = f(int(fd)) + if ready(err) { + return + } + } + }) + if doErr != nil { + // Error from syscall.RawConn methods. Conventionally the standard + // library does not wrap internal/poll errors in os.NewSyscallError. + return *new(T), doErr + } + + // Result from user function. + return t, os.NewSyscallError(op, err) +} + +// ready indicates readiness based on the value of err. +func ready(err error) bool { + switch err { + case unix.EAGAIN, unix.EINPROGRESS, unix.EINTR: + // When a socket is in non-blocking mode, we might see a variety of errors: + // - EAGAIN: most common case for a socket read not being ready + // - EINPROGRESS: reported by some sockets when first calling connect + // - EINTR: system call interrupted, more frequently occurs in Go 1.14+ + // because goroutines can be asynchronously preempted + // + // Return false to let the poller wait for readiness. See the source code + // for internal/poll.FD.RawRead for more details. + return false + default: + // Ready regardless of whether there was an error or no error. + return true + } +} + +// Darwin and FreeBSD can't read or write 2GB+ files at a time, +// even on 64-bit systems. +// The same is true of socket implementations on many systems. +// See golang.org/issue/7812 and golang.org/issue/16266. +// Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned. +const maxRW = 1 << 30 diff --git a/vendor/github.com/mdlayher/socket/conn_linux.go b/vendor/github.com/mdlayher/socket/conn_linux.go new file mode 100644 index 000000000..081194f32 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/conn_linux.go @@ -0,0 +1,118 @@ +//go:build linux +// +build linux + +package socket + +import ( + "context" + "os" + "unsafe" + + "golang.org/x/net/bpf" + "golang.org/x/sys/unix" +) + +// IoctlKCMClone wraps ioctl(2) for unix.KCMClone values, but returns a Conn +// rather than a raw file descriptor. +func (c *Conn) IoctlKCMClone() (*Conn, error) { + info, err := controlT(c, "ioctl", unix.IoctlKCMClone) + if err != nil { + return nil, err + } + + // Successful clone, wrap in a Conn for use by the caller. + return New(int(info.Fd), c.name) +} + +// IoctlKCMAttach wraps ioctl(2) for unix.KCMAttach values. +func (c *Conn) IoctlKCMAttach(info unix.KCMAttach) error { + return c.control("ioctl", func(fd int) error { + return unix.IoctlKCMAttach(fd, info) + }) +} + +// IoctlKCMUnattach wraps ioctl(2) for unix.KCMUnattach values. +func (c *Conn) IoctlKCMUnattach(info unix.KCMUnattach) error { + return c.control("ioctl", func(fd int) error { + return unix.IoctlKCMUnattach(fd, info) + }) +} + +// PidfdGetfd wraps pidfd_getfd(2) for a Conn which wraps a pidfd, but returns a +// Conn rather than a raw file descriptor. +func (c *Conn) PidfdGetfd(targetFD, flags int) (*Conn, error) { + outFD, err := controlT(c, "pidfd_getfd", func(fd int) (int, error) { + return unix.PidfdGetfd(fd, targetFD, flags) + }) + if err != nil { + return nil, err + } + + // Successful getfd, wrap in a Conn for use by the caller. + return New(outFD, c.name) +} + +// PidfdSendSignal wraps pidfd_send_signal(2) for a Conn which wraps a Linux +// pidfd. +func (c *Conn) PidfdSendSignal(sig unix.Signal, info *unix.Siginfo, flags int) error { + return c.control("pidfd_send_signal", func(fd int) error { + return unix.PidfdSendSignal(fd, sig, info, flags) + }) +} + +// SetBPF attaches an assembled BPF program to a Conn. +func (c *Conn) SetBPF(filter []bpf.RawInstruction) error { + // We can't point to the first instruction in the array if no instructions + // are present. + if len(filter) == 0 { + return os.NewSyscallError("setsockopt", unix.EINVAL) + } + + prog := unix.SockFprog{ + Len: uint16(len(filter)), + Filter: (*unix.SockFilter)(unsafe.Pointer(&filter[0])), + } + + return c.SetsockoptSockFprog(unix.SOL_SOCKET, unix.SO_ATTACH_FILTER, &prog) +} + +// RemoveBPF removes a BPF filter from a Conn. +func (c *Conn) RemoveBPF() error { + // 0 argument is ignored. + return c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_DETACH_FILTER, 0) +} + +// SetsockoptPacketMreq wraps setsockopt(2) for unix.PacketMreq values. +func (c *Conn) SetsockoptPacketMreq(level, opt int, mreq *unix.PacketMreq) error { + return c.control("setsockopt", func(fd int) error { + return unix.SetsockoptPacketMreq(fd, level, opt, mreq) + }) +} + +// SetsockoptSockFprog wraps setsockopt(2) for unix.SockFprog values. +func (c *Conn) SetsockoptSockFprog(level, opt int, fprog *unix.SockFprog) error { + return c.control("setsockopt", func(fd int) error { + return unix.SetsockoptSockFprog(fd, level, opt, fprog) + }) +} + +// GetsockoptTpacketStats wraps getsockopt(2) for unix.TpacketStats values. +func (c *Conn) GetsockoptTpacketStats(level, name int) (*unix.TpacketStats, error) { + return controlT(c, "getsockopt", func(fd int) (*unix.TpacketStats, error) { + return unix.GetsockoptTpacketStats(fd, level, name) + }) +} + +// GetsockoptTpacketStatsV3 wraps getsockopt(2) for unix.TpacketStatsV3 values. +func (c *Conn) GetsockoptTpacketStatsV3(level, name int) (*unix.TpacketStatsV3, error) { + return controlT(c, "getsockopt", func(fd int) (*unix.TpacketStatsV3, error) { + return unix.GetsockoptTpacketStatsV3(fd, level, name) + }) +} + +// Waitid wraps waitid(2). +func (c *Conn) Waitid(idType int, info *unix.Siginfo, options int, rusage *unix.Rusage) error { + return c.read(context.Background(), "waitid", func(fd int) error { + return unix.Waitid(idType, fd, info, options, rusage) + }) +} diff --git a/vendor/github.com/mdlayher/socket/doc.go b/vendor/github.com/mdlayher/socket/doc.go new file mode 100644 index 000000000..7d4566c90 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/doc.go @@ -0,0 +1,13 @@ +// Package socket provides a low-level network connection type which integrates +// with Go's runtime network poller to provide asynchronous I/O and deadline +// support. +// +// This package focuses on UNIX-like operating systems which make use of BSD +// sockets system call APIs. It is meant to be used as a foundation for the +// creation of operating system-specific socket packages, for socket families +// such as Linux's AF_NETLINK, AF_PACKET, or AF_VSOCK. This package should not +// be used directly in end user applications. +// +// Any use of package socket should be guarded by build tags, as one would also +// use when importing the syscall or golang.org/x/sys packages. +package socket diff --git a/vendor/github.com/mdlayher/socket/netns_linux.go b/vendor/github.com/mdlayher/socket/netns_linux.go new file mode 100644 index 000000000..b29115ad1 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/netns_linux.go @@ -0,0 +1,150 @@ +//go:build linux +// +build linux + +package socket + +import ( + "errors" + "fmt" + "os" + "runtime" + + "golang.org/x/sync/errgroup" + "golang.org/x/sys/unix" +) + +// errNetNSDisabled is returned when network namespaces are unavailable on +// a given system. +var errNetNSDisabled = errors.New("socket: Linux network namespaces are not enabled on this system") + +// withNetNS invokes fn within the context of the network namespace specified by +// fd, while also managing the logic required to safely do so by manipulating +// thread-local state. +func withNetNS(fd int, fn func() (*Conn, error)) (*Conn, error) { + var ( + eg errgroup.Group + conn *Conn + ) + + eg.Go(func() error { + // Retrieve and store the calling OS thread's network namespace so the + // thread can be reassigned to it after creating a socket in another network + // namespace. + runtime.LockOSThread() + + ns, err := threadNetNS() + if err != nil { + // No thread-local manipulation, unlock. + runtime.UnlockOSThread() + return err + } + defer ns.Close() + + // Beyond this point, the thread's network namespace is poisoned. Do not + // unlock the OS thread until all network namespace manipulation completes + // to avoid returning to the caller with altered thread-local state. + + // Assign the current OS thread the goroutine is locked to to the given + // network namespace. + if err := ns.Set(fd); err != nil { + return err + } + + // Attempt Conn creation and unconditionally restore the original namespace. + c, err := fn() + if nerr := ns.Restore(); nerr != nil { + // Failed to restore original namespace. Return an error and allow the + // runtime to terminate the thread. + if err == nil { + _ = c.Close() + } + + return nerr + } + + // No more thread-local state manipulation; return the new Conn. + runtime.UnlockOSThread() + conn = c + return nil + }) + + if err := eg.Wait(); err != nil { + return nil, err + } + + return conn, nil +} + +// A netNS is a handle that can manipulate network namespaces. +// +// Operations performed on a netNS must use runtime.LockOSThread before +// manipulating any network namespaces. +type netNS struct { + // The handle to a network namespace. + f *os.File + + // Indicates if network namespaces are disabled on this system, and thus + // operations should become a no-op or return errors. + disabled bool +} + +// threadNetNS constructs a netNS using the network namespace of the calling +// thread. If the namespace is not the default namespace, runtime.LockOSThread +// should be invoked first. +func threadNetNS() (*netNS, error) { + return fileNetNS(fmt.Sprintf("/proc/self/task/%d/ns/net", unix.Gettid())) +} + +// fileNetNS opens file and creates a netNS. fileNetNS should only be called +// directly in tests. +func fileNetNS(file string) (*netNS, error) { + f, err := os.Open(file) + switch { + case err == nil: + return &netNS{f: f}, nil + case os.IsNotExist(err): + // Network namespaces are not enabled on this system. Use this signal + // to return errors elsewhere if the caller explicitly asks for a + // network namespace to be set. + return &netNS{disabled: true}, nil + default: + return nil, err + } +} + +// Close releases the handle to a network namespace. +func (n *netNS) Close() error { + return n.do(func() error { return n.f.Close() }) +} + +// FD returns a file descriptor which represents the network namespace. +func (n *netNS) FD() int { + if n.disabled { + // No reasonable file descriptor value in this case, so specify a + // non-existent one. + return -1 + } + + return int(n.f.Fd()) +} + +// Restore restores the original network namespace for the calling thread. +func (n *netNS) Restore() error { + return n.do(func() error { return n.Set(n.FD()) }) +} + +// Set sets a new network namespace for the current thread using fd. +func (n *netNS) Set(fd int) error { + return n.do(func() error { + return os.NewSyscallError("setns", unix.Setns(fd, unix.CLONE_NEWNET)) + }) +} + +// do runs fn if network namespaces are enabled on this system. +func (n *netNS) do(fn func() error) error { + if n.disabled { + return errNetNSDisabled + } + + return fn() +} diff --git a/vendor/github.com/mdlayher/socket/netns_others.go b/vendor/github.com/mdlayher/socket/netns_others.go new file mode 100644 index 000000000..4cceb3d04 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/netns_others.go @@ -0,0 +1,14 @@ +//go:build !linux +// +build !linux + +package socket + +import ( + "fmt" + "runtime" +) + +// withNetNS returns an error on non-Linux systems. +func withNetNS(_ int, _ func() (*Conn, error)) (*Conn, error) { + return nil, fmt.Errorf("socket: Linux network namespace support is not available on %s", runtime.GOOS) +} diff --git a/vendor/github.com/mdlayher/socket/setbuffer_linux.go b/vendor/github.com/mdlayher/socket/setbuffer_linux.go new file mode 100644 index 000000000..0d4aa4417 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/setbuffer_linux.go @@ -0,0 +1,24 @@ +//go:build linux +// +build linux + +package socket + +import "golang.org/x/sys/unix" + +// setReadBuffer wraps the SO_RCVBUF{,FORCE} setsockopt(2) options. +func (c *Conn) setReadBuffer(bytes int) error { + err := c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_RCVBUFFORCE, bytes) + if err != nil { + err = c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_RCVBUF, bytes) + } + return err +} + +// setWriteBuffer wraps the SO_SNDBUF{,FORCE} setsockopt(2) options. +func (c *Conn) setWriteBuffer(bytes int) error { + err := c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_SNDBUFFORCE, bytes) + if err != nil { + err = c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_SNDBUF, bytes) + } + return err +} diff --git a/vendor/github.com/mdlayher/socket/setbuffer_others.go b/vendor/github.com/mdlayher/socket/setbuffer_others.go new file mode 100644 index 000000000..72b36dbe3 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/setbuffer_others.go @@ -0,0 +1,16 @@ +//go:build !linux +// +build !linux + +package socket + +import "golang.org/x/sys/unix" + +// setReadBuffer wraps the SO_RCVBUF setsockopt(2) option. +func (c *Conn) setReadBuffer(bytes int) error { + return c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_RCVBUF, bytes) +} + +// setWriteBuffer wraps the SO_SNDBUF setsockopt(2) option. +func (c *Conn) setWriteBuffer(bytes int) error { + return c.SetsockoptInt(unix.SOL_SOCKET, unix.SO_SNDBUF, bytes) +} diff --git a/vendor/github.com/mdlayher/socket/typ_cloexec_nonblock.go b/vendor/github.com/mdlayher/socket/typ_cloexec_nonblock.go new file mode 100644 index 000000000..40e834310 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/typ_cloexec_nonblock.go @@ -0,0 +1,12 @@ +//go:build !darwin +// +build !darwin + +package socket + +import "golang.org/x/sys/unix" + +const ( + // These operating systems support CLOEXEC and NONBLOCK socket options. + flagCLOEXEC = true + socketFlags = unix.SOCK_CLOEXEC | unix.SOCK_NONBLOCK +) diff --git a/vendor/github.com/mdlayher/socket/typ_none.go b/vendor/github.com/mdlayher/socket/typ_none.go new file mode 100644 index 000000000..9bbb1aab5 --- /dev/null +++ b/vendor/github.com/mdlayher/socket/typ_none.go @@ -0,0 +1,11 @@ +//go:build darwin +// +build darwin + +package socket + +const ( + // These operating systems do not support CLOEXEC and NONBLOCK socket + // options. + flagCLOEXEC = false + socketFlags = 0 +) diff --git a/vendor/github.com/pierrec/lz4/v4/.gitignore b/vendor/github.com/pierrec/lz4/v4/.gitignore new file mode 100644 index 000000000..5d7e88de0 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/.gitignore @@ -0,0 +1,36 @@ +# Created by https://www.gitignore.io/api/macos + +### macOS ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# End of https://www.gitignore.io/api/macos + +cmd/*/*exe +.idea + +fuzz/*.zip diff --git a/vendor/github.com/pierrec/lz4/v4/LICENSE b/vendor/github.com/pierrec/lz4/v4/LICENSE new file mode 100644 index 000000000..bd899d835 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2015, Pierre Curto +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of xxHash nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/vendor/github.com/pierrec/lz4/v4/README.md b/vendor/github.com/pierrec/lz4/v4/README.md new file mode 100644 index 000000000..dee77545b --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/README.md @@ -0,0 +1,92 @@ +# lz4 : LZ4 compression in pure Go + +[![Go Reference](https://pkg.go.dev/badge/github.com/pierrec/lz4/v4.svg)](https://pkg.go.dev/github.com/pierrec/lz4/v4) +[![CI](https://github.com/pierrec/lz4/workflows/ci/badge.svg)](https://github.com/pierrec/lz4/actions) +[![Go Report Card](https://goreportcard.com/badge/github.com/pierrec/lz4)](https://goreportcard.com/report/github.com/pierrec/lz4) +[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/pierrec/lz4.svg?style=social)](https://github.com/pierrec/lz4/tags) + +## Overview + +This package provides a streaming interface to [LZ4 data streams](http://fastcompression.blogspot.fr/2013/04/lz4-streaming-format-final.html) as well as low level compress and uncompress functions for LZ4 data blocks. +The implementation is based on the reference C [one](https://github.com/lz4/lz4). + +## Install + +Assuming you have the go toolchain installed: + +``` +go get github.com/pierrec/lz4/v4 +``` + +There is a command line interface tool to compress and decompress LZ4 files. + +``` +go install github.com/pierrec/lz4/v4/cmd/lz4c@latest +``` + +Usage + +``` +Usage of lz4c: + -version + print the program version + +Subcommands: +Compress the given files or from stdin to stdout. +compress [arguments] [ ...] + -bc + enable block checksum + -l int + compression level (0=fastest) + -sc + disable stream checksum + -size string + block max size [64K,256K,1M,4M] (default "4M") + +Uncompress the given files or from stdin to stdout. +uncompress [arguments] [ ...] + +``` + + +## Example + +``` +// Compress and uncompress an input string. +s := "hello world" +r := strings.NewReader(s) + +// The pipe will uncompress the data from the writer. +pr, pw := io.Pipe() +zw := lz4.NewWriter(pw) +zr := lz4.NewReader(pr) + +go func() { + // Compress the input string. + _, _ = io.Copy(zw, r) + _ = zw.Close() // Make sure the writer is closed + _ = pw.Close() // Terminate the pipe +}() + +_, _ = io.Copy(os.Stdout, zr) + +// Output: +// hello world +``` + +## Contributing + +Contributions are very welcome for bug fixing, performance improvements...! + +- Open an issue with a proper description +- Send a pull request with appropriate test case(s) + +## Contributors + +Thanks to all [contributors](https://github.com/pierrec/lz4/graphs/contributors) so far! + +Special thanks to [@Zariel](https://github.com/Zariel) for his asm implementation of the decoder. + +Special thanks to [@greatroar](https://github.com/greatroar) for his work on the asm implementations of the decoder for amd64 and arm64. + +Special thanks to [@klauspost](https://github.com/klauspost) for his work on optimizing the code. diff --git a/vendor/github.com/pierrec/lz4/v4/compressing_reader.go b/vendor/github.com/pierrec/lz4/v4/compressing_reader.go new file mode 100644 index 000000000..8df0dc76d --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/compressing_reader.go @@ -0,0 +1,222 @@ +package lz4 + +import ( + "errors" + "io" + + "github.com/pierrec/lz4/v4/internal/lz4block" + "github.com/pierrec/lz4/v4/internal/lz4errors" + "github.com/pierrec/lz4/v4/internal/lz4stream" +) + +type crState int + +const ( + crStateInitial crState = iota + crStateReading + crStateFlushing + crStateDone +) + +type CompressingReader struct { + state crState + src io.ReadCloser // source reader + level lz4block.CompressionLevel // how hard to try + frame *lz4stream.Frame // frame being built + in []byte + out ovWriter + handler func(int) +} + +// NewCompressingReader creates a reader which reads compressed data from +// raw stream. This makes it a logical opposite of a normal lz4.Reader. +// We require an io.ReadCloser as an underlying source for compatibility +// with Go's http.Request. +func NewCompressingReader(src io.ReadCloser) *CompressingReader { + zrd := &CompressingReader { + frame: lz4stream.NewFrame(), + } + + _ = zrd.Apply(DefaultBlockSizeOption, DefaultChecksumOption, defaultOnBlockDone) + zrd.Reset(src) + + return zrd +} + +// Source exposes the underlying source stream for introspection and control. +func (zrd *CompressingReader) Source() io.ReadCloser { + return zrd.src +} + +// Close simply invokes the underlying stream Close method. This method is +// provided for the benefit of Go http client/server, which relies on Close +// for goroutine termination. +func (zrd *CompressingReader) Close() error { + return zrd.src.Close() +} + +// Apply applies useful options to the lz4 encoder. +func (zrd *CompressingReader) Apply(options ...Option) (err error) { + if zrd.state != crStateInitial { + return lz4errors.ErrOptionClosedOrError + } + + zrd.Reset(zrd.src) + + for _, o := range options { + if err = o(zrd); err != nil { + return + } + } + return +} + +func (*CompressingReader) private() {} + +func (zrd *CompressingReader) init() error { + zrd.frame.InitW(&zrd.out, 1, false) + size := zrd.frame.Descriptor.Flags.BlockSizeIndex() + zrd.in = size.Get() + return zrd.frame.Descriptor.Write(zrd.frame, &zrd.out) +} + +// Read allows reading of lz4 compressed data +func (zrd *CompressingReader) Read(p []byte) (n int, err error) { + defer func() { + if err != nil { + zrd.state = crStateDone + } + }() + + if !zrd.out.reset(p) { + return len(p), nil + } + + switch zrd.state { + case crStateInitial: + err = zrd.init() + if err != nil { + return + } + zrd.state = crStateReading + case crStateDone: + return 0, errors.New("This reader is done") + case crStateFlushing: + if zrd.out.dataPos > 0 { + n = zrd.out.dataPos + zrd.out.data = nil + zrd.out.dataPos = 0 + return + } else { + zrd.state = crStateDone + return 0, io.EOF + } + } + + for zrd.state == crStateReading { + block := zrd.frame.Blocks.Block + + var rCount int + rCount, err = io.ReadFull(zrd.src, zrd.in) + switch err { + case nil: + err = block.Compress( + zrd.frame, zrd.in[ : rCount], zrd.level, + ).Write(zrd.frame, &zrd.out) + zrd.handler(len(block.Data)) + if err != nil { + return + } + + if zrd.out.dataPos == len(zrd.out.data) { + n = zrd.out.dataPos + zrd.out.dataPos = 0 + zrd.out.data = nil + return + } + case io.EOF, io.ErrUnexpectedEOF: // read may be partial + if rCount > 0 { + err = block.Compress( + zrd.frame, zrd.in[ : rCount], zrd.level, + ).Write(zrd.frame, &zrd.out) + zrd.handler(len(block.Data)) + if err != nil { + return + } + } + + err = zrd.frame.CloseW(&zrd.out, 1) + if err != nil { + return + } + zrd.state = crStateFlushing + + n = zrd.out.dataPos + zrd.out.dataPos = 0 + zrd.out.data = nil + return + default: + return + } + } + + err = lz4errors.ErrInternalUnhandledState + return +} + +// Reset makes the stream usable again; mostly handy to reuse lz4 encoder +// instances. +func (zrd *CompressingReader) Reset(src io.ReadCloser) { + zrd.frame.Reset(1) + zrd.state = crStateInitial + zrd.src = src + zrd.out.clear() +} + +type ovWriter struct { + data []byte + ov []byte + dataPos int + ovPos int +} + +func (wr *ovWriter) Write(p []byte) (n int, err error) { + count := copy(wr.data[wr.dataPos : ], p) + wr.dataPos += count + + if count < len(p) { + wr.ov = append(wr.ov, p[count : ]...) + } + + return len(p), nil +} + +func (wr *ovWriter) reset(out []byte) bool { + ovRem := len(wr.ov) - wr.ovPos + + if ovRem >= len(out) { + wr.ovPos += copy(out, wr.ov[wr.ovPos : ]) + return false + } + + if ovRem > 0 { + copy(out, wr.ov[wr.ovPos : ]) + wr.ov = wr.ov[ : 0] + wr.ovPos = 0 + wr.dataPos = ovRem + } else if wr.ovPos > 0 { + wr.ov = wr.ov[ : 0] + wr.ovPos = 0 + wr.dataPos = 0 + } + + wr.data = out + return true +} + +func (wr *ovWriter) clear() { + wr.data = nil + wr.dataPos = 0 + wr.ov = wr.ov[ : 0] + wr.ovPos = 0 +} diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/block.go b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/block.go new file mode 100644 index 000000000..fec8adb03 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/block.go @@ -0,0 +1,481 @@ +package lz4block + +import ( + "encoding/binary" + "math/bits" + "sync" + + "github.com/pierrec/lz4/v4/internal/lz4errors" +) + +const ( + // The following constants are used to setup the compression algorithm. + minMatch = 4 // the minimum size of the match sequence size (4 bytes) + winSizeLog = 16 // LZ4 64Kb window size limit + winSize = 1 << winSizeLog + winMask = winSize - 1 // 64Kb window of previous data for dependent blocks + + // hashLog determines the size of the hash table used to quickly find a previous match position. + // Its value influences the compression speed and memory usage, the lower the faster, + // but at the expense of the compression ratio. + // 16 seems to be the best compromise for fast compression. + hashLog = 16 + htSize = 1 << hashLog + + mfLimit = 10 + minMatch // The last match cannot start within the last 14 bytes. +) + +func recoverBlock(e *error) { + if r := recover(); r != nil && *e == nil { + *e = lz4errors.ErrInvalidSourceShortBuffer + } +} + +// blockHash hashes the lower 6 bytes into a value < htSize. +func blockHash(x uint64) uint32 { + const prime6bytes = 227718039650203 + return uint32(((x << (64 - 48)) * prime6bytes) >> (64 - hashLog)) +} + +func CompressBlockBound(n int) int { + return n + n/255 + 16 +} + +func UncompressBlock(src, dst, dict []byte) (int, error) { + if len(src) == 0 { + return 0, nil + } + if di := decodeBlock(dst, src, dict); di >= 0 { + return di, nil + } + return 0, lz4errors.ErrInvalidSourceShortBuffer +} + +type Compressor struct { + // Offsets are at most 64kiB, so we can store only the lower 16 bits of + // match positions: effectively, an offset from some 64kiB block boundary. + // + // When we retrieve such an offset, we interpret it as relative to the last + // block boundary si &^ 0xffff, or the one before, (si &^ 0xffff) - 0x10000, + // depending on which of these is inside the current window. If a table + // entry was generated more than 64kiB back in the input, we find out by + // inspecting the input stream. + table [htSize]uint16 + + // Bitmap indicating which positions in the table are in use. + // This allows us to quickly reset the table for reuse, + // without having to zero everything. + inUse [htSize / 32]uint32 +} + +// Get returns the position of a presumptive match for the hash h. +// The match may be a false positive due to a hash collision or an old entry. +// If si < winSize, the return value may be negative. +func (c *Compressor) get(h uint32, si int) int { + h &= htSize - 1 + i := 0 + if c.inUse[h/32]&(1<<(h%32)) != 0 { + i = int(c.table[h]) + } + i += si &^ winMask + if i >= si { + // Try previous 64kiB block (negative when in first block). + i -= winSize + } + return i +} + +func (c *Compressor) put(h uint32, si int) { + h &= htSize - 1 + c.table[h] = uint16(si) + c.inUse[h/32] |= 1 << (h % 32) +} + +func (c *Compressor) reset() { c.inUse = [htSize / 32]uint32{} } + +var compressorPool = sync.Pool{New: func() interface{} { return new(Compressor) }} + +func CompressBlock(src, dst []byte) (int, error) { + c := compressorPool.Get().(*Compressor) + n, err := c.CompressBlock(src, dst) + compressorPool.Put(c) + return n, err +} + +func (c *Compressor) CompressBlock(src, dst []byte) (int, error) { + // Zero out reused table to avoid non-deterministic output (issue #65). + c.reset() + + // Return 0, nil only if the destination buffer size is < CompressBlockBound. + isNotCompressible := len(dst) < CompressBlockBound(len(src)) + + // adaptSkipLog sets how quickly the compressor begins skipping blocks when data is incompressible. + // This significantly speeds up incompressible data and usually has very small impact on compression. + // bytes to skip = 1 + (bytes since last match >> adaptSkipLog) + const adaptSkipLog = 7 + + // si: Current position of the search. + // anchor: Position of the current literals. + var si, di, anchor int + sn := len(src) - mfLimit + if sn <= 0 { + goto lastLiterals + } + + // Fast scan strategy: the hash table only stores the last 4 bytes sequences. + for si < sn { + // Hash the next 6 bytes (sequence)... + match := binary.LittleEndian.Uint64(src[si:]) + h := blockHash(match) + h2 := blockHash(match >> 8) + + // We check a match at s, s+1 and s+2 and pick the first one we get. + // Checking 3 only requires us to load the source one. + ref := c.get(h, si) + ref2 := c.get(h2, si+1) + c.put(h, si) + c.put(h2, si+1) + + offset := si - ref + + if offset <= 0 || offset >= winSize || uint32(match) != binary.LittleEndian.Uint32(src[ref:]) { + // No match. Start calculating another hash. + // The processor can usually do this out-of-order. + h = blockHash(match >> 16) + ref3 := c.get(h, si+2) + + // Check the second match at si+1 + si += 1 + offset = si - ref2 + + if offset <= 0 || offset >= winSize || uint32(match>>8) != binary.LittleEndian.Uint32(src[ref2:]) { + // No match. Check the third match at si+2 + si += 1 + offset = si - ref3 + c.put(h, si) + + if offset <= 0 || offset >= winSize || uint32(match>>16) != binary.LittleEndian.Uint32(src[ref3:]) { + // Skip one extra byte (at si+3) before we check 3 matches again. + si += 2 + (si-anchor)>>adaptSkipLog + continue + } + } + } + + // Match found. + lLen := si - anchor // Literal length. + // We already matched 4 bytes. + mLen := 4 + + // Extend backwards if we can, reducing literals. + tOff := si - offset - 1 + for lLen > 0 && tOff >= 0 && src[si-1] == src[tOff] { + si-- + tOff-- + lLen-- + mLen++ + } + + // Add the match length, so we continue search at the end. + // Use mLen to store the offset base. + si, mLen = si+mLen, si+minMatch + + // Find the longest match by looking by batches of 8 bytes. + for si+8 <= sn { + x := binary.LittleEndian.Uint64(src[si:]) ^ binary.LittleEndian.Uint64(src[si-offset:]) + if x == 0 { + si += 8 + } else { + // Stop is first non-zero byte. + si += bits.TrailingZeros64(x) >> 3 + break + } + } + + mLen = si - mLen + if di >= len(dst) { + return 0, lz4errors.ErrInvalidSourceShortBuffer + } + if mLen < 0xF { + dst[di] = byte(mLen) + } else { + dst[di] = 0xF + } + + // Encode literals length. + if lLen < 0xF { + dst[di] |= byte(lLen << 4) + } else { + dst[di] |= 0xF0 + di++ + l := lLen - 0xF + for ; l >= 0xFF && di < len(dst); l -= 0xFF { + dst[di] = 0xFF + di++ + } + if di >= len(dst) { + return 0, lz4errors.ErrInvalidSourceShortBuffer + } + dst[di] = byte(l) + } + di++ + + // Literals. + if di+lLen > len(dst) { + return 0, lz4errors.ErrInvalidSourceShortBuffer + } + copy(dst[di:di+lLen], src[anchor:anchor+lLen]) + di += lLen + 2 + anchor = si + + // Encode offset. + if di > len(dst) { + return 0, lz4errors.ErrInvalidSourceShortBuffer + } + dst[di-2], dst[di-1] = byte(offset), byte(offset>>8) + + // Encode match length part 2. + if mLen >= 0xF { + for mLen -= 0xF; mLen >= 0xFF && di < len(dst); mLen -= 0xFF { + dst[di] = 0xFF + di++ + } + if di >= len(dst) { + return 0, lz4errors.ErrInvalidSourceShortBuffer + } + dst[di] = byte(mLen) + di++ + } + // Check if we can load next values. + if si >= sn { + break + } + // Hash match end-2 + h = blockHash(binary.LittleEndian.Uint64(src[si-2:])) + c.put(h, si-2) + } + +lastLiterals: + if isNotCompressible && anchor == 0 { + // Incompressible. + return 0, nil + } + + // Last literals. + if di >= len(dst) { + return 0, lz4errors.ErrInvalidSourceShortBuffer + } + lLen := len(src) - anchor + if lLen < 0xF { + dst[di] = byte(lLen << 4) + } else { + dst[di] = 0xF0 + di++ + for lLen -= 0xF; lLen >= 0xFF && di < len(dst); lLen -= 0xFF { + dst[di] = 0xFF + di++ + } + if di >= len(dst) { + return 0, lz4errors.ErrInvalidSourceShortBuffer + } + dst[di] = byte(lLen) + } + di++ + + // Write the last literals. + if isNotCompressible && di >= anchor { + // Incompressible. + return 0, nil + } + if di+len(src)-anchor > len(dst) { + return 0, lz4errors.ErrInvalidSourceShortBuffer + } + di += copy(dst[di:di+len(src)-anchor], src[anchor:]) + return di, nil +} + +// blockHash hashes 4 bytes into a value < winSize. +func blockHashHC(x uint32) uint32 { + const hasher uint32 = 2654435761 // Knuth multiplicative hash. + return x * hasher >> (32 - winSizeLog) +} + +type CompressorHC struct { + // hashTable: stores the last position found for a given hash + // chainTable: stores previous positions for a given hash + hashTable, chainTable [htSize]int + needsReset bool +} + +var compressorHCPool = sync.Pool{New: func() interface{} { return new(CompressorHC) }} + +func CompressBlockHC(src, dst []byte, depth CompressionLevel) (int, error) { + c := compressorHCPool.Get().(*CompressorHC) + n, err := c.CompressBlock(src, dst, depth) + compressorHCPool.Put(c) + return n, err +} + +func (c *CompressorHC) CompressBlock(src, dst []byte, depth CompressionLevel) (_ int, err error) { + if c.needsReset { + // Zero out reused table to avoid non-deterministic output (issue #65). + c.hashTable = [htSize]int{} + c.chainTable = [htSize]int{} + } + c.needsReset = true // Only false on first call. + + defer recoverBlock(&err) + + // Return 0, nil only if the destination buffer size is < CompressBlockBound. + isNotCompressible := len(dst) < CompressBlockBound(len(src)) + + // adaptSkipLog sets how quickly the compressor begins skipping blocks when data is incompressible. + // This significantly speeds up incompressible data and usually has very small impact on compression. + // bytes to skip = 1 + (bytes since last match >> adaptSkipLog) + const adaptSkipLog = 7 + + var si, di, anchor int + sn := len(src) - mfLimit + if sn <= 0 { + goto lastLiterals + } + + if depth == 0 { + depth = winSize + } + + for si < sn { + // Hash the next 4 bytes (sequence). + match := binary.LittleEndian.Uint32(src[si:]) + h := blockHashHC(match) + + // Follow the chain until out of window and give the longest match. + mLen := 0 + offset := 0 + for next, try := c.hashTable[h], depth; try > 0 && next > 0 && si-next < winSize; next, try = c.chainTable[next&winMask], try-1 { + // The first (mLen==0) or next byte (mLen>=minMatch) at current match length + // must match to improve on the match length. + if src[next+mLen] != src[si+mLen] { + continue + } + ml := 0 + // Compare the current position with a previous with the same hash. + for ml < sn-si { + x := binary.LittleEndian.Uint64(src[next+ml:]) ^ binary.LittleEndian.Uint64(src[si+ml:]) + if x == 0 { + ml += 8 + } else { + // Stop is first non-zero byte. + ml += bits.TrailingZeros64(x) >> 3 + break + } + } + if ml < minMatch || ml <= mLen { + // Match too small (>adaptSkipLog + continue + } + + // Match found. + // Update hash/chain tables with overlapping bytes: + // si already hashed, add everything from si+1 up to the match length. + winStart := si + 1 + if ws := si + mLen - winSize; ws > winStart { + winStart = ws + } + for si, ml := winStart, si+mLen; si < ml; { + match >>= 8 + match |= uint32(src[si+3]) << 24 + h := blockHashHC(match) + c.chainTable[si&winMask] = c.hashTable[h] + c.hashTable[h] = si + si++ + } + + lLen := si - anchor + si += mLen + mLen -= minMatch // Match length does not include minMatch. + + if mLen < 0xF { + dst[di] = byte(mLen) + } else { + dst[di] = 0xF + } + + // Encode literals length. + if lLen < 0xF { + dst[di] |= byte(lLen << 4) + } else { + dst[di] |= 0xF0 + di++ + l := lLen - 0xF + for ; l >= 0xFF; l -= 0xFF { + dst[di] = 0xFF + di++ + } + dst[di] = byte(l) + } + di++ + + // Literals. + copy(dst[di:di+lLen], src[anchor:anchor+lLen]) + di += lLen + anchor = si + + // Encode offset. + di += 2 + dst[di-2], dst[di-1] = byte(offset), byte(offset>>8) + + // Encode match length part 2. + if mLen >= 0xF { + for mLen -= 0xF; mLen >= 0xFF; mLen -= 0xFF { + dst[di] = 0xFF + di++ + } + dst[di] = byte(mLen) + di++ + } + } + + if isNotCompressible && anchor == 0 { + // Incompressible. + return 0, nil + } + + // Last literals. +lastLiterals: + lLen := len(src) - anchor + if lLen < 0xF { + dst[di] = byte(lLen << 4) + } else { + dst[di] = 0xF0 + di++ + lLen -= 0xF + for ; lLen >= 0xFF; lLen -= 0xFF { + dst[di] = 0xFF + di++ + } + dst[di] = byte(lLen) + } + di++ + + // Write the last literals. + if isNotCompressible && di >= anchor { + // Incompressible. + return 0, nil + } + di += copy(dst[di:di+len(src)-anchor], src[anchor:]) + return di, nil +} diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/blocks.go b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/blocks.go new file mode 100644 index 000000000..138083d94 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/blocks.go @@ -0,0 +1,87 @@ +// Package lz4block provides LZ4 BlockSize types and pools of buffers. +package lz4block + +import "sync" + +const ( + Block64Kb uint32 = 1 << (16 + iota*2) + Block256Kb + Block1Mb + Block4Mb + Block8Mb = 2 * Block4Mb +) + +var ( + BlockPool64K = sync.Pool{New: func() interface{} { return make([]byte, Block64Kb) }} + BlockPool256K = sync.Pool{New: func() interface{} { return make([]byte, Block256Kb) }} + BlockPool1M = sync.Pool{New: func() interface{} { return make([]byte, Block1Mb) }} + BlockPool4M = sync.Pool{New: func() interface{} { return make([]byte, Block4Mb) }} + BlockPool8M = sync.Pool{New: func() interface{} { return make([]byte, Block8Mb) }} +) + +func Index(b uint32) BlockSizeIndex { + switch b { + case Block64Kb: + return 4 + case Block256Kb: + return 5 + case Block1Mb: + return 6 + case Block4Mb: + return 7 + case Block8Mb: // only valid in legacy mode + return 3 + } + return 0 +} + +func IsValid(b uint32) bool { + return Index(b) > 0 +} + +type BlockSizeIndex uint8 + +func (b BlockSizeIndex) IsValid() bool { + switch b { + case 4, 5, 6, 7: + return true + } + return false +} + +func (b BlockSizeIndex) Get() []byte { + var buf interface{} + switch b { + case 4: + buf = BlockPool64K.Get() + case 5: + buf = BlockPool256K.Get() + case 6: + buf = BlockPool1M.Get() + case 7: + buf = BlockPool4M.Get() + case 3: + buf = BlockPool8M.Get() + } + return buf.([]byte) +} + +func Put(buf []byte) { + // Safeguard: do not allow invalid buffers. + switch c := cap(buf); uint32(c) { + case Block64Kb: + BlockPool64K.Put(buf[:c]) + case Block256Kb: + BlockPool256K.Put(buf[:c]) + case Block1Mb: + BlockPool1M.Put(buf[:c]) + case Block4Mb: + BlockPool4M.Put(buf[:c]) + case Block8Mb: + BlockPool8M.Put(buf[:c]) + } +} + +type CompressionLevel uint32 + +const Fast CompressionLevel = 0 diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_amd64.s b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_amd64.s new file mode 100644 index 000000000..1d00133fa --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_amd64.s @@ -0,0 +1,448 @@ +// +build !appengine +// +build gc +// +build !noasm + +#include "go_asm.h" +#include "textflag.h" + +// AX scratch +// BX scratch +// CX literal and match lengths +// DX token, match offset +// +// DI &dst +// SI &src +// R8 &dst + len(dst) +// R9 &src + len(src) +// R11 &dst +// R12 short output end +// R13 short input end +// R14 &dict +// R15 len(dict) + +// func decodeBlock(dst, src, dict []byte) int +TEXT ·decodeBlock(SB), NOSPLIT, $48-80 + MOVQ dst_base+0(FP), DI + MOVQ DI, R11 + MOVQ dst_len+8(FP), R8 + ADDQ DI, R8 + + MOVQ src_base+24(FP), SI + MOVQ src_len+32(FP), R9 + CMPQ R9, $0 + JE err_corrupt + ADDQ SI, R9 + + MOVQ dict_base+48(FP), R14 + MOVQ dict_len+56(FP), R15 + + // shortcut ends + // short output end + MOVQ R8, R12 + SUBQ $32, R12 + // short input end + MOVQ R9, R13 + SUBQ $16, R13 + + XORL CX, CX + +loop: + // token := uint32(src[si]) + MOVBLZX (SI), DX + INCQ SI + + // lit_len = token >> 4 + // if lit_len > 0 + // CX = lit_len + MOVL DX, CX + SHRL $4, CX + + // if lit_len != 0xF + CMPL CX, $0xF + JEQ lit_len_loop + CMPQ DI, R12 + JAE copy_literal + CMPQ SI, R13 + JAE copy_literal + + // copy shortcut + + // A two-stage shortcut for the most common case: + // 1) If the literal length is 0..14, and there is enough space, + // enter the shortcut and copy 16 bytes on behalf of the literals + // (in the fast mode, only 8 bytes can be safely copied this way). + // 2) Further if the match length is 4..18, copy 18 bytes in a similar + // manner; but we ensure that there's enough space in the output for + // those 18 bytes earlier, upon entering the shortcut (in other words, + // there is a combined check for both stages). + + // copy literal + MOVOU (SI), X0 + MOVOU X0, (DI) + ADDQ CX, DI + ADDQ CX, SI + + MOVL DX, CX + ANDL $0xF, CX + + // The second stage: prepare for match copying, decode full info. + // If it doesn't work out, the info won't be wasted. + // offset := uint16(data[:2]) + MOVWLZX (SI), DX + TESTL DX, DX + JE err_corrupt + ADDQ $2, SI + JC err_short_buf + + MOVQ DI, AX + SUBQ DX, AX + JC err_corrupt + CMPQ AX, DI + JA err_short_buf + + // if we can't do the second stage then jump straight to read the + // match length, we already have the offset. + CMPL CX, $0xF + JEQ match_len_loop_pre + CMPL DX, $8 + JLT match_len_loop_pre + CMPQ AX, R11 + JB match_len_loop_pre + + // memcpy(op + 0, match + 0, 8); + MOVQ (AX), BX + MOVQ BX, (DI) + // memcpy(op + 8, match + 8, 8); + MOVQ 8(AX), BX + MOVQ BX, 8(DI) + // memcpy(op +16, match +16, 2); + MOVW 16(AX), BX + MOVW BX, 16(DI) + + LEAQ const_minMatch(DI)(CX*1), DI + + // shortcut complete, load next token + JMP loopcheck + + // Read the rest of the literal length: + // do { BX = src[si++]; lit_len += BX } while (BX == 0xFF). +lit_len_loop: + CMPQ SI, R9 + JAE err_short_buf + + MOVBLZX (SI), BX + INCQ SI + ADDQ BX, CX + + CMPB BX, $0xFF + JE lit_len_loop + +copy_literal: + // bounds check src and dst + MOVQ SI, AX + ADDQ CX, AX + JC err_short_buf + CMPQ AX, R9 + JA err_short_buf + + MOVQ DI, BX + ADDQ CX, BX + JC err_short_buf + CMPQ BX, R8 + JA err_short_buf + + // Copy literals of <=48 bytes through the XMM registers. + CMPQ CX, $48 + JGT memmove_lit + + // if len(dst[di:]) < 48 + MOVQ R8, AX + SUBQ DI, AX + CMPQ AX, $48 + JLT memmove_lit + + // if len(src[si:]) < 48 + MOVQ R9, BX + SUBQ SI, BX + CMPQ BX, $48 + JLT memmove_lit + + MOVOU (SI), X0 + MOVOU 16(SI), X1 + MOVOU 32(SI), X2 + MOVOU X0, (DI) + MOVOU X1, 16(DI) + MOVOU X2, 32(DI) + + ADDQ CX, SI + ADDQ CX, DI + + JMP finish_lit_copy + +memmove_lit: + // memmove(to, from, len) + MOVQ DI, 0(SP) + MOVQ SI, 8(SP) + MOVQ CX, 16(SP) + + // Spill registers. Increment SI, DI now so we don't need to save CX. + ADDQ CX, DI + ADDQ CX, SI + MOVQ DI, 24(SP) + MOVQ SI, 32(SP) + MOVL DX, 40(SP) + + CALL runtime·memmove(SB) + + // restore registers + MOVQ 24(SP), DI + MOVQ 32(SP), SI + MOVL 40(SP), DX + + // recalc initial values + MOVQ dst_base+0(FP), R8 + MOVQ R8, R11 + ADDQ dst_len+8(FP), R8 + MOVQ src_base+24(FP), R9 + ADDQ src_len+32(FP), R9 + MOVQ dict_base+48(FP), R14 + MOVQ dict_len+56(FP), R15 + MOVQ R8, R12 + SUBQ $32, R12 + MOVQ R9, R13 + SUBQ $16, R13 + +finish_lit_copy: + // CX := mLen + // free up DX to use for offset + MOVL DX, CX + ANDL $0xF, CX + + CMPQ SI, R9 + JAE end + + // offset + // si += 2 + // DX := int(src[si-2]) | int(src[si-1])<<8 + ADDQ $2, SI + JC err_short_buf + CMPQ SI, R9 + JA err_short_buf + MOVWQZX -2(SI), DX + + // 0 offset is invalid + TESTL DX, DX + JEQ err_corrupt + +match_len_loop_pre: + // if mlen != 0xF + CMPB CX, $0xF + JNE copy_match + + // do { BX = src[si++]; mlen += BX } while (BX == 0xFF). +match_len_loop: + CMPQ SI, R9 + JAE err_short_buf + + MOVBLZX (SI), BX + INCQ SI + ADDQ BX, CX + + CMPB BX, $0xFF + JE match_len_loop + +copy_match: + ADDQ $const_minMatch, CX + + // check we have match_len bytes left in dst + // di+match_len < len(dst) + MOVQ DI, AX + ADDQ CX, AX + JC err_short_buf + CMPQ AX, R8 + JA err_short_buf + + // DX = offset + // CX = match_len + // BX = &dst + (di - offset) + MOVQ DI, BX + SUBQ DX, BX + + // check BX is within dst + // if BX < &dst + JC copy_match_from_dict + CMPQ BX, R11 + JBE copy_match_from_dict + + // if offset + match_len < di + LEAQ (BX)(CX*1), AX + CMPQ DI, AX + JA copy_interior_match + + // AX := len(dst[:di]) + // MOVQ DI, AX + // SUBQ R11, AX + + // copy 16 bytes at a time + // if di-offset < 16 copy 16-(di-offset) bytes to di + // then do the remaining + +copy_match_loop: + // for match_len >= 0 + // dst[di] = dst[i] + // di++ + // i++ + MOVB (BX), AX + MOVB AX, (DI) + INCQ DI + INCQ BX + DECQ CX + JNZ copy_match_loop + + JMP loopcheck + +copy_interior_match: + CMPQ CX, $16 + JGT memmove_match + + // if len(dst[di:]) < 16 + MOVQ R8, AX + SUBQ DI, AX + CMPQ AX, $16 + JLT memmove_match + + MOVOU (BX), X0 + MOVOU X0, (DI) + + ADDQ CX, DI + XORL CX, CX + JMP loopcheck + +copy_match_from_dict: + // CX = match_len + // BX = &dst + (di - offset) + + // AX = offset - di = dict_bytes_available => count of bytes potentially covered by the dictionary + MOVQ R11, AX + SUBQ BX, AX + + // BX = len(dict) - dict_bytes_available + MOVQ R15, BX + SUBQ AX, BX + JS err_short_dict + + ADDQ R14, BX + + // if match_len > dict_bytes_available, match fits entirely within external dictionary : just copy + CMPQ CX, AX + JLT memmove_match + + // The match stretches over the dictionary and our block + // 1) copy what comes from the dictionary + // AX = dict_bytes_available = copy_size + // BX = &dict_end - copy_size + // CX = match_len + + // memmove(to, from, len) + MOVQ DI, 0(SP) + MOVQ BX, 8(SP) + MOVQ AX, 16(SP) + // store extra stuff we want to recover + // spill + MOVQ DI, 24(SP) + MOVQ SI, 32(SP) + MOVQ CX, 40(SP) + CALL runtime·memmove(SB) + + // restore registers + MOVQ 16(SP), AX // copy_size + MOVQ 24(SP), DI + MOVQ 32(SP), SI + MOVQ 40(SP), CX // match_len + + // recalc initial values + MOVQ dst_base+0(FP), R8 + MOVQ R8, R11 // TODO: make these sensible numbers + ADDQ dst_len+8(FP), R8 + MOVQ src_base+24(FP), R9 + ADDQ src_len+32(FP), R9 + MOVQ dict_base+48(FP), R14 + MOVQ dict_len+56(FP), R15 + MOVQ R8, R12 + SUBQ $32, R12 + MOVQ R9, R13 + SUBQ $16, R13 + + // di+=copy_size + ADDQ AX, DI + + // 2) copy the rest from the current block + // CX = match_len - copy_size = rest_size + SUBQ AX, CX + MOVQ R11, BX + + // check if we have a copy overlap + // AX = &dst + rest_size + MOVQ CX, AX + ADDQ BX, AX + // if &dst + rest_size > di, copy byte by byte + CMPQ AX, DI + + JA copy_match_loop + +memmove_match: + // memmove(to, from, len) + MOVQ DI, 0(SP) + MOVQ BX, 8(SP) + MOVQ CX, 16(SP) + + // Spill registers. Increment DI now so we don't need to save CX. + ADDQ CX, DI + MOVQ DI, 24(SP) + MOVQ SI, 32(SP) + + CALL runtime·memmove(SB) + + // restore registers + MOVQ 24(SP), DI + MOVQ 32(SP), SI + + // recalc initial values + MOVQ dst_base+0(FP), R8 + MOVQ R8, R11 // TODO: make these sensible numbers + ADDQ dst_len+8(FP), R8 + MOVQ src_base+24(FP), R9 + ADDQ src_len+32(FP), R9 + MOVQ R8, R12 + SUBQ $32, R12 + MOVQ R9, R13 + SUBQ $16, R13 + MOVQ dict_base+48(FP), R14 + MOVQ dict_len+56(FP), R15 + XORL CX, CX + +loopcheck: + // for si < len(src) + CMPQ SI, R9 + JB loop + +end: + // Remaining length must be zero. + TESTQ CX, CX + JNE err_corrupt + + SUBQ R11, DI + MOVQ DI, ret+72(FP) + RET + +err_corrupt: + MOVQ $-1, ret+72(FP) + RET + +err_short_buf: + MOVQ $-2, ret+72(FP) + RET + +err_short_dict: + MOVQ $-3, ret+72(FP) + RET diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_arm.s b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_arm.s new file mode 100644 index 000000000..20b21fcf1 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_arm.s @@ -0,0 +1,231 @@ +// +build gc +// +build !noasm + +#include "go_asm.h" +#include "textflag.h" + +// Register allocation. +#define dst R0 +#define dstorig R1 +#define src R2 +#define dstend R3 +#define srcend R4 +#define match R5 // Match address. +#define dictend R6 +#define token R7 +#define len R8 // Literal and match lengths. +#define offset R7 // Match offset; overlaps with token. +#define tmp1 R9 +#define tmp2 R11 +#define tmp3 R12 + +// func decodeBlock(dst, src, dict []byte) int +TEXT ·decodeBlock(SB), NOFRAME+NOSPLIT, $-4-40 + MOVW dst_base +0(FP), dst + MOVW dst_len +4(FP), dstend + MOVW src_base +12(FP), src + MOVW src_len +16(FP), srcend + + CMP $0, srcend + BEQ shortSrc + + ADD dst, dstend + ADD src, srcend + + MOVW dst, dstorig + +loop: + // Read token. Extract literal length. + MOVBU.P 1(src), token + MOVW token >> 4, len + CMP $15, len + BNE readLitlenDone + +readLitlenLoop: + CMP src, srcend + BEQ shortSrc + MOVBU.P 1(src), tmp1 + ADD.S tmp1, len + BVS shortDst + CMP $255, tmp1 + BEQ readLitlenLoop + +readLitlenDone: + CMP $0, len + BEQ copyLiteralDone + + // Bounds check dst+len and src+len. + ADD.S dst, len, tmp1 + ADD.CC.S src, len, tmp2 + BCS shortSrc + CMP dstend, tmp1 + //BHI shortDst // Uncomment for distinct error codes. + CMP.LS srcend, tmp2 + BHI shortSrc + + // Copy literal. + CMP $4, len + BLO copyLiteralFinish + + // Copy 0-3 bytes until src is aligned. + TST $1, src + MOVBU.NE.P 1(src), tmp1 + MOVB.NE.P tmp1, 1(dst) + SUB.NE $1, len + + TST $2, src + MOVHU.NE.P 2(src), tmp2 + MOVB.NE.P tmp2, 1(dst) + MOVW.NE tmp2 >> 8, tmp1 + MOVB.NE.P tmp1, 1(dst) + SUB.NE $2, len + + B copyLiteralLoopCond + +copyLiteralLoop: + // Aligned load, unaligned write. + MOVW.P 4(src), tmp1 + MOVW tmp1 >> 8, tmp2 + MOVB tmp2, 1(dst) + MOVW tmp1 >> 16, tmp3 + MOVB tmp3, 2(dst) + MOVW tmp1 >> 24, tmp2 + MOVB tmp2, 3(dst) + MOVB.P tmp1, 4(dst) +copyLiteralLoopCond: + // Loop until len-4 < 0. + SUB.S $4, len + BPL copyLiteralLoop + +copyLiteralFinish: + // Copy remaining 0-3 bytes. + // At this point, len may be < 0, but len&3 is still accurate. + TST $1, len + MOVB.NE.P 1(src), tmp3 + MOVB.NE.P tmp3, 1(dst) + TST $2, len + MOVB.NE.P 2(src), tmp1 + MOVB.NE.P tmp1, 2(dst) + MOVB.NE -1(src), tmp2 + MOVB.NE tmp2, -1(dst) + +copyLiteralDone: + // Initial part of match length. + // This frees up the token register for reuse as offset. + AND $15, token, len + + CMP src, srcend + BEQ end + + // Read offset. + ADD.S $2, src + BCS shortSrc + CMP srcend, src + BHI shortSrc + MOVBU -2(src), offset + MOVBU -1(src), tmp1 + ORR.S tmp1 << 8, offset + BEQ corrupt + + // Read rest of match length. + CMP $15, len + BNE readMatchlenDone + +readMatchlenLoop: + CMP src, srcend + BEQ shortSrc + MOVBU.P 1(src), tmp1 + ADD.S tmp1, len + BVS shortDst + CMP $255, tmp1 + BEQ readMatchlenLoop + +readMatchlenDone: + // Bounds check dst+len+minMatch. + ADD.S dst, len, tmp1 + ADD.CC.S $const_minMatch, tmp1 + BCS shortDst + CMP dstend, tmp1 + BHI shortDst + + RSB dst, offset, match + CMP dstorig, match + BGE copyMatch4 + + // match < dstorig means the match starts in the dictionary, + // at len(dict) - offset + (dst - dstorig). + MOVW dict_base+24(FP), match + MOVW dict_len +28(FP), dictend + + ADD $const_minMatch, len + + RSB dst, dstorig, tmp1 + RSB dictend, offset, tmp2 + ADD.S tmp2, tmp1 + BMI shortDict + ADD match, dictend + ADD tmp1, match + +copyDict: + MOVBU.P 1(match), tmp1 + MOVB.P tmp1, 1(dst) + SUB.S $1, len + CMP.NE match, dictend + BNE copyDict + + // If the match extends beyond the dictionary, the rest is at dstorig. + CMP $0, len + BEQ copyMatchDone + MOVW dstorig, match + B copyMatch + + // Copy a regular match. + // Since len+minMatch is at least four, we can do a 4× unrolled + // byte copy loop. Using MOVW instead of four byte loads is faster, + // but to remain portable we'd have to align match first, which is + // too expensive. By alternating loads and stores, we also handle + // the case offset < 4. +copyMatch4: + SUB.S $4, len + MOVBU.P 4(match), tmp1 + MOVB.P tmp1, 4(dst) + MOVBU -3(match), tmp2 + MOVB tmp2, -3(dst) + MOVBU -2(match), tmp3 + MOVB tmp3, -2(dst) + MOVBU -1(match), tmp1 + MOVB tmp1, -1(dst) + BPL copyMatch4 + + // Restore len, which is now negative. + ADD.S $4, len + BEQ copyMatchDone + +copyMatch: + // Finish with a byte-at-a-time copy. + SUB.S $1, len + MOVBU.P 1(match), tmp2 + MOVB.P tmp2, 1(dst) + BNE copyMatch + +copyMatchDone: + CMP src, srcend + BNE loop + +end: + CMP $0, len + BNE corrupt + SUB dstorig, dst, tmp1 + MOVW tmp1, ret+36(FP) + RET + + // The error cases have distinct labels so we can put different + // return codes here when debugging, or if the error returns need to + // be changed. +shortDict: +shortDst: +shortSrc: +corrupt: + MOVW $-1, tmp1 + MOVW tmp1, ret+36(FP) + RET diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_arm64.s b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_arm64.s new file mode 100644 index 000000000..d2fe11b8e --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_arm64.s @@ -0,0 +1,241 @@ +// +build gc +// +build !noasm + +// This implementation assumes that strict alignment checking is turned off. +// The Go compiler makes the same assumption. + +#include "go_asm.h" +#include "textflag.h" + +// Register allocation. +#define dst R0 +#define dstorig R1 +#define src R2 +#define dstend R3 +#define dstend16 R4 // dstend - 16 +#define srcend R5 +#define srcend16 R6 // srcend - 16 +#define match R7 // Match address. +#define dict R8 +#define dictlen R9 +#define dictend R10 +#define token R11 +#define len R12 // Literal and match lengths. +#define lenRem R13 +#define offset R14 // Match offset. +#define tmp1 R15 +#define tmp2 R16 +#define tmp3 R17 +#define tmp4 R19 + +// func decodeBlock(dst, src, dict []byte) int +TEXT ·decodeBlock(SB), NOFRAME+NOSPLIT, $0-80 + LDP dst_base+0(FP), (dst, dstend) + ADD dst, dstend + MOVD dst, dstorig + + LDP src_base+24(FP), (src, srcend) + CBZ srcend, shortSrc + ADD src, srcend + + // dstend16 = max(dstend-16, 0) and similarly for srcend16. + SUBS $16, dstend, dstend16 + CSEL LO, ZR, dstend16, dstend16 + SUBS $16, srcend, srcend16 + CSEL LO, ZR, srcend16, srcend16 + + LDP dict_base+48(FP), (dict, dictlen) + ADD dict, dictlen, dictend + +loop: + // Read token. Extract literal length. + MOVBU.P 1(src), token + LSR $4, token, len + CMP $15, len + BNE readLitlenDone + +readLitlenLoop: + CMP src, srcend + BEQ shortSrc + MOVBU.P 1(src), tmp1 + ADDS tmp1, len + BVS shortDst + CMP $255, tmp1 + BEQ readLitlenLoop + +readLitlenDone: + CBZ len, copyLiteralDone + + // Bounds check dst+len and src+len. + ADDS dst, len, tmp1 + BCS shortSrc + ADDS src, len, tmp2 + BCS shortSrc + CMP dstend, tmp1 + BHI shortDst + CMP srcend, tmp2 + BHI shortSrc + + // Copy literal. + SUBS $16, len + BLO copyLiteralShort + +copyLiteralLoop: + LDP.P 16(src), (tmp1, tmp2) + STP.P (tmp1, tmp2), 16(dst) + SUBS $16, len + BPL copyLiteralLoop + + // Copy (final part of) literal of length 0-15. + // If we have >=16 bytes left in src and dst, just copy 16 bytes. +copyLiteralShort: + CMP dstend16, dst + CCMP LO, src, srcend16, $0b0010 // 0010 = preserve carry (LO). + BHS copyLiteralShortEnd + + AND $15, len + + LDP (src), (tmp1, tmp2) + ADD len, src + STP (tmp1, tmp2), (dst) + ADD len, dst + + B copyLiteralDone + + // Safe but slow copy near the end of src, dst. +copyLiteralShortEnd: + TBZ $3, len, 3(PC) + MOVD.P 8(src), tmp1 + MOVD.P tmp1, 8(dst) + TBZ $2, len, 3(PC) + MOVW.P 4(src), tmp2 + MOVW.P tmp2, 4(dst) + TBZ $1, len, 3(PC) + MOVH.P 2(src), tmp3 + MOVH.P tmp3, 2(dst) + TBZ $0, len, 3(PC) + MOVBU.P 1(src), tmp4 + MOVB.P tmp4, 1(dst) + +copyLiteralDone: + // Initial part of match length. + AND $15, token, len + + CMP src, srcend + BEQ end + + // Read offset. + ADDS $2, src + BCS shortSrc + CMP srcend, src + BHI shortSrc + MOVHU -2(src), offset + CBZ offset, corrupt + + // Read rest of match length. + CMP $15, len + BNE readMatchlenDone + +readMatchlenLoop: + CMP src, srcend + BEQ shortSrc + MOVBU.P 1(src), tmp1 + ADDS tmp1, len + BVS shortDst + CMP $255, tmp1 + BEQ readMatchlenLoop + +readMatchlenDone: + ADD $const_minMatch, len + + // Bounds check dst+len. + ADDS dst, len, tmp2 + BCS shortDst + CMP dstend, tmp2 + BHI shortDst + + SUB offset, dst, match + CMP dstorig, match + BHS copyMatchTry8 + + // match < dstorig means the match starts in the dictionary, + // at len(dict) - offset + (dst - dstorig). + SUB dstorig, dst, tmp1 + SUB offset, dictlen, tmp2 + ADDS tmp2, tmp1 + BMI shortDict + ADD dict, tmp1, match + +copyDict: + MOVBU.P 1(match), tmp3 + MOVB.P tmp3, 1(dst) + SUBS $1, len + CCMP NE, dictend, match, $0b0100 // 0100 sets the Z (EQ) flag. + BNE copyDict + + CBZ len, copyMatchDone + + // If the match extends beyond the dictionary, the rest is at dstorig. + // Recompute the offset for the next check. + MOVD dstorig, match + SUB dstorig, dst, offset + +copyMatchTry8: + // Copy doublewords if both len and offset are at least eight. + // A 16-at-a-time loop doesn't provide a further speedup. + CMP $8, len + CCMP HS, offset, $8, $0 + BLO copyMatchTry4 + + AND $7, len, lenRem + SUB $8, len +copyMatchLoop8: + MOVD.P 8(match), tmp1 + MOVD.P tmp1, 8(dst) + SUBS $8, len + BPL copyMatchLoop8 + + MOVD (match)(len), tmp2 // match+len == match+lenRem-8. + ADD lenRem, dst + MOVD $0, len + MOVD tmp2, -8(dst) + B copyMatchDone + +copyMatchTry4: + // Copy words if both len and offset are at least four. + CMP $4, len + CCMP HS, offset, $4, $0 + BLO copyMatchLoop1 + + MOVWU.P 4(match), tmp2 + MOVWU.P tmp2, 4(dst) + SUBS $4, len + BEQ copyMatchDone + +copyMatchLoop1: + // Byte-at-a-time copy for small offsets <= 3. + MOVBU.P 1(match), tmp2 + MOVB.P tmp2, 1(dst) + SUBS $1, len + BNE copyMatchLoop1 + +copyMatchDone: + CMP src, srcend + BNE loop + +end: + CBNZ len, corrupt + SUB dstorig, dst, tmp1 + MOVD tmp1, ret+72(FP) + RET + + // The error cases have distinct labels so we can put different + // return codes here when debugging, or if the error returns need to + // be changed. +shortDict: +shortDst: +shortSrc: +corrupt: + MOVD $-1, tmp1 + MOVD tmp1, ret+72(FP) + RET diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_asm.go b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_asm.go new file mode 100644 index 000000000..8d9023d10 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_asm.go @@ -0,0 +1,10 @@ +//go:build (amd64 || arm || arm64) && !appengine && gc && !noasm +// +build amd64 arm arm64 +// +build !appengine +// +build gc +// +build !noasm + +package lz4block + +//go:noescape +func decodeBlock(dst, src, dict []byte) int diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_other.go b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_other.go new file mode 100644 index 000000000..9f568fbb1 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4block/decode_other.go @@ -0,0 +1,139 @@ +//go:build (!amd64 && !arm && !arm64) || appengine || !gc || noasm +// +build !amd64,!arm,!arm64 appengine !gc noasm + +package lz4block + +import ( + "encoding/binary" +) + +func decodeBlock(dst, src, dict []byte) (ret int) { + // Restrict capacities so we don't read or write out of bounds. + dst = dst[:len(dst):len(dst)] + src = src[:len(src):len(src)] + + const hasError = -2 + + if len(src) == 0 { + return hasError + } + + defer func() { + if recover() != nil { + ret = hasError + } + }() + + var si, di uint + for si < uint(len(src)) { + // Literals and match lengths (token). + b := uint(src[si]) + si++ + + // Literals. + if lLen := b >> 4; lLen > 0 { + switch { + case lLen < 0xF && si+16 < uint(len(src)): + // Shortcut 1 + // if we have enough room in src and dst, and the literals length + // is small enough (0..14) then copy all 16 bytes, even if not all + // are part of the literals. + copy(dst[di:], src[si:si+16]) + si += lLen + di += lLen + if mLen := b & 0xF; mLen < 0xF { + // Shortcut 2 + // if the match length (4..18) fits within the literals, then copy + // all 18 bytes, even if not all are part of the literals. + mLen += 4 + if offset := u16(src[si:]); mLen <= offset && offset < di { + i := di - offset + // The remaining buffer may not hold 18 bytes. + // See https://github.com/pierrec/lz4/issues/51. + if end := i + 18; end <= uint(len(dst)) { + copy(dst[di:], dst[i:end]) + si += 2 + di += mLen + continue + } + } + } + case lLen == 0xF: + for { + x := uint(src[si]) + if lLen += x; int(lLen) < 0 { + return hasError + } + si++ + if x != 0xFF { + break + } + } + fallthrough + default: + copy(dst[di:di+lLen], src[si:si+lLen]) + si += lLen + di += lLen + } + } + + mLen := b & 0xF + if si == uint(len(src)) && mLen == 0 { + break + } else if si >= uint(len(src)) { + return hasError + } + + offset := u16(src[si:]) + if offset == 0 { + return hasError + } + si += 2 + + // Match. + mLen += minMatch + if mLen == minMatch+0xF { + for { + x := uint(src[si]) + if mLen += x; int(mLen) < 0 { + return hasError + } + si++ + if x != 0xFF { + break + } + } + } + + // Copy the match. + if di < offset { + // The match is beyond our block, meaning the first part + // is in the dictionary. + fromDict := dict[uint(len(dict))+di-offset:] + n := uint(copy(dst[di:di+mLen], fromDict)) + di += n + if mLen -= n; mLen == 0 { + continue + } + // We copied n = offset-di bytes from the dictionary, + // then set di = di+n = offset, so the following code + // copies from dst[di-offset:] = dst[0:]. + } + + expanded := dst[di-offset:] + if mLen > offset { + // Efficiently copy the match dst[di-offset:di] into the dst slice. + bytesToCopy := offset * (mLen / offset) + for n := offset; n <= bytesToCopy+offset; n *= 2 { + copy(expanded[n:], expanded[:n]) + } + di += bytesToCopy + mLen -= bytesToCopy + } + di += uint(copy(dst[di:di+mLen], expanded[:mLen])) + } + + return int(di) +} + +func u16(p []byte) uint { return uint(binary.LittleEndian.Uint16(p)) } diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4errors/errors.go b/vendor/github.com/pierrec/lz4/v4/internal/lz4errors/errors.go new file mode 100644 index 000000000..710ea4281 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4errors/errors.go @@ -0,0 +1,19 @@ +package lz4errors + +type Error string + +func (e Error) Error() string { return string(e) } + +const ( + ErrInvalidSourceShortBuffer Error = "lz4: invalid source or destination buffer too short" + ErrInvalidFrame Error = "lz4: bad magic number" + ErrInternalUnhandledState Error = "lz4: unhandled state" + ErrInvalidHeaderChecksum Error = "lz4: invalid header checksum" + ErrInvalidBlockChecksum Error = "lz4: invalid block checksum" + ErrInvalidFrameChecksum Error = "lz4: invalid frame checksum" + ErrOptionInvalidCompressionLevel Error = "lz4: invalid compression level" + ErrOptionClosedOrError Error = "lz4: cannot apply options on closed or in error object" + ErrOptionInvalidBlockSize Error = "lz4: invalid block size" + ErrOptionNotApplicable Error = "lz4: option not applicable" + ErrWriterNotClosed Error = "lz4: writer not closed" +) diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/block.go b/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/block.go new file mode 100644 index 000000000..e96465460 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/block.go @@ -0,0 +1,348 @@ +package lz4stream + +import ( + "encoding/binary" + "fmt" + "io" + "sync" + + "github.com/pierrec/lz4/v4/internal/lz4block" + "github.com/pierrec/lz4/v4/internal/lz4errors" + "github.com/pierrec/lz4/v4/internal/xxh32" +) + +type Blocks struct { + Block *FrameDataBlock + Blocks chan chan *FrameDataBlock + mu sync.Mutex + err error +} + +func (b *Blocks) initW(f *Frame, dst io.Writer, num int) { + if num == 1 { + b.Blocks = nil + b.Block = NewFrameDataBlock(f) + return + } + b.Block = nil + if cap(b.Blocks) != num { + b.Blocks = make(chan chan *FrameDataBlock, num) + } + // goroutine managing concurrent block compression goroutines. + go func() { + // Process next block compression item. + for c := range b.Blocks { + // Read the next compressed block result. + // Waiting here ensures that the blocks are output in the order they were sent. + // The incoming channel is always closed as it indicates to the caller that + // the block has been processed. + block := <-c + if block == nil { + // Notify the block compression routine that we are done with its result. + // This is used when a sentinel block is sent to terminate the compression. + close(c) + return + } + // Do not attempt to write the block upon any previous failure. + if b.err == nil { + // Write the block. + if err := block.Write(f, dst); err != nil { + // Keep the first error. + b.err = err + // All pending compression goroutines need to shut down, so we need to keep going. + } + } + close(c) + } + }() +} + +func (b *Blocks) close(f *Frame, num int) error { + if num == 1 { + if b.Block != nil { + b.Block.Close(f) + } + err := b.err + b.err = nil + return err + } + if b.Blocks == nil { + err := b.err + b.err = nil + return err + } + c := make(chan *FrameDataBlock) + b.Blocks <- c + c <- nil + <-c + err := b.err + b.err = nil + return err +} + +// ErrorR returns any error set while uncompressing a stream. +func (b *Blocks) ErrorR() error { + b.mu.Lock() + defer b.mu.Unlock() + return b.err +} + +// initR returns a channel that streams the uncompressed blocks if in concurrent +// mode and no error. When the channel is closed, check for any error with b.ErrorR. +// +// If not in concurrent mode, the uncompressed block is b.Block and the returned error +// needs to be checked. +func (b *Blocks) initR(f *Frame, num int, src io.Reader) (chan []byte, error) { + size := f.Descriptor.Flags.BlockSizeIndex() + if num == 1 { + b.Blocks = nil + b.Block = NewFrameDataBlock(f) + return nil, nil + } + b.Block = nil + blocks := make(chan chan []byte, num) + // data receives the uncompressed blocks. + data := make(chan []byte) + // Read blocks from the source sequentially + // and uncompress them concurrently. + + // In legacy mode, accrue the uncompress sizes in cum. + var cum uint32 + go func() { + var cumx uint32 + var err error + for b.ErrorR() == nil { + block := NewFrameDataBlock(f) + cumx, err = block.Read(f, src, 0) + if err != nil { + block.Close(f) + break + } + // Recheck for an error as reading may be slow and uncompressing is expensive. + if b.ErrorR() != nil { + block.Close(f) + break + } + c := make(chan []byte) + blocks <- c + go func() { + defer block.Close(f) + data, err := block.Uncompress(f, size.Get(), nil, false) + if err != nil { + b.closeR(err) + // Close the block channel to indicate an error. + close(c) + } else { + c <- data + } + }() + } + // End the collection loop and the data channel. + c := make(chan []byte) + blocks <- c + c <- nil // signal the collection loop that we are done + <-c // wait for the collect loop to complete + if f.isLegacy() && cum == cumx { + err = io.EOF + } + b.closeR(err) + close(data) + }() + // Collect the uncompressed blocks and make them available + // on the returned channel. + go func(leg bool) { + defer close(blocks) + skipBlocks := false + for c := range blocks { + buf, ok := <-c + if !ok { + // A closed channel indicates an error. + // All remaining channels should be discarded. + skipBlocks = true + continue + } + if buf == nil { + // Signal to end the loop. + close(c) + return + } + if skipBlocks { + // A previous error has occurred, skipping remaining channels. + continue + } + // Perform checksum now as the blocks are received in order. + if f.Descriptor.Flags.ContentChecksum() { + _, _ = f.checksum.Write(buf) + } + if leg { + cum += uint32(len(buf)) + } + data <- buf + close(c) + } + }(f.isLegacy()) + return data, nil +} + +// closeR safely sets the error on b if not already set. +func (b *Blocks) closeR(err error) { + b.mu.Lock() + if b.err == nil { + b.err = err + } + b.mu.Unlock() +} + +func NewFrameDataBlock(f *Frame) *FrameDataBlock { + buf := f.Descriptor.Flags.BlockSizeIndex().Get() + return &FrameDataBlock{Data: buf, data: buf} +} + +type FrameDataBlock struct { + Size DataBlockSize + Data []byte // compressed or uncompressed data (.data or .src) + Checksum uint32 + data []byte // buffer for compressed data + src []byte // uncompressed data + err error // used in concurrent mode +} + +func (b *FrameDataBlock) Close(f *Frame) { + b.Size = 0 + b.Checksum = 0 + b.err = nil + if b.data != nil { + // Block was not already closed. + lz4block.Put(b.data) + b.Data = nil + b.data = nil + b.src = nil + } +} + +// Block compression errors are ignored since the buffer is sized appropriately. +func (b *FrameDataBlock) Compress(f *Frame, src []byte, level lz4block.CompressionLevel) *FrameDataBlock { + data := b.data + if f.isLegacy() { + data = data[:cap(data)] + } else { + data = data[:len(src)] // trigger the incompressible flag in CompressBlock + } + var n int + switch level { + case lz4block.Fast: + n, _ = lz4block.CompressBlock(src, data) + default: + n, _ = lz4block.CompressBlockHC(src, data, level) + } + if n == 0 { + b.Size.UncompressedSet(true) + b.Data = src + } else { + b.Size.UncompressedSet(false) + b.Data = data[:n] + } + b.Size.sizeSet(len(b.Data)) + b.src = src // keep track of the source for content checksum + + if f.Descriptor.Flags.BlockChecksum() { + b.Checksum = xxh32.ChecksumZero(src) + } + return b +} + +func (b *FrameDataBlock) Write(f *Frame, dst io.Writer) error { + // Write is called in the same order as blocks are compressed, + // so content checksum must be done here. + if f.Descriptor.Flags.ContentChecksum() { + _, _ = f.checksum.Write(b.src) + } + buf := f.buf[:] + binary.LittleEndian.PutUint32(buf, uint32(b.Size)) + if _, err := dst.Write(buf[:4]); err != nil { + return err + } + + if _, err := dst.Write(b.Data); err != nil { + return err + } + + if b.Checksum == 0 { + return nil + } + binary.LittleEndian.PutUint32(buf, b.Checksum) + _, err := dst.Write(buf[:4]) + return err +} + +// Read updates b with the next block data, size and checksum if available. +func (b *FrameDataBlock) Read(f *Frame, src io.Reader, cum uint32) (uint32, error) { + x, err := f.readUint32(src) + if err != nil { + return 0, err + } + if f.isLegacy() { + switch x { + case frameMagicLegacy: + // Concatenated legacy frame. + return b.Read(f, src, cum) + case cum: + // Only works in non concurrent mode, for concurrent mode + // it is handled separately. + // Linux kernel format appends the total uncompressed size at the end. + return 0, io.EOF + } + } else if x == 0 { + // Marker for end of stream. + return 0, io.EOF + } + b.Size = DataBlockSize(x) + + size := b.Size.size() + if size > cap(b.data) { + return x, lz4errors.ErrOptionInvalidBlockSize + } + b.data = b.data[:size] + if _, err := io.ReadFull(src, b.data); err != nil { + return x, err + } + if f.Descriptor.Flags.BlockChecksum() { + sum, err := f.readUint32(src) + if err != nil { + return 0, err + } + b.Checksum = sum + } + return x, nil +} + +func (b *FrameDataBlock) Uncompress(f *Frame, dst, dict []byte, sum bool) ([]byte, error) { + if b.Size.Uncompressed() { + n := copy(dst, b.data) + dst = dst[:n] + } else { + n, err := lz4block.UncompressBlock(b.data, dst, dict) + if err != nil { + return nil, err + } + dst = dst[:n] + } + if f.Descriptor.Flags.BlockChecksum() { + if c := xxh32.ChecksumZero(dst); c != b.Checksum { + err := fmt.Errorf("%w: got %x; expected %x", lz4errors.ErrInvalidBlockChecksum, c, b.Checksum) + return nil, err + } + } + if sum && f.Descriptor.Flags.ContentChecksum() { + _, _ = f.checksum.Write(dst) + } + return dst, nil +} + +func (f *Frame) readUint32(r io.Reader) (x uint32, err error) { + if _, err = io.ReadFull(r, f.buf[:4]); err != nil { + return + } + x = binary.LittleEndian.Uint32(f.buf[:4]) + return +} diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/frame.go b/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/frame.go new file mode 100644 index 000000000..18192a943 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/frame.go @@ -0,0 +1,204 @@ +// Package lz4stream provides the types that support reading and writing LZ4 data streams. +package lz4stream + +import ( + "encoding/binary" + "fmt" + "io" + "io/ioutil" + + "github.com/pierrec/lz4/v4/internal/lz4block" + "github.com/pierrec/lz4/v4/internal/lz4errors" + "github.com/pierrec/lz4/v4/internal/xxh32" +) + +//go:generate go run gen.go + +const ( + frameMagic uint32 = 0x184D2204 + frameSkipMagic uint32 = 0x184D2A50 + frameMagicLegacy uint32 = 0x184C2102 +) + +func NewFrame() *Frame { + return &Frame{} +} + +type Frame struct { + buf [15]byte // frame descriptor needs at most 4(magic)+4+8+1=11 bytes + Magic uint32 + Descriptor FrameDescriptor + Blocks Blocks + Checksum uint32 + checksum xxh32.XXHZero +} + +// Reset allows reusing the Frame. +// The Descriptor configuration is not modified. +func (f *Frame) Reset(num int) { + f.Magic = 0 + f.Descriptor.Checksum = 0 + f.Descriptor.ContentSize = 0 + _ = f.Blocks.close(f, num) + f.Checksum = 0 +} + +func (f *Frame) InitW(dst io.Writer, num int, legacy bool) { + if legacy { + f.Magic = frameMagicLegacy + idx := lz4block.Index(lz4block.Block8Mb) + f.Descriptor.Flags.BlockSizeIndexSet(idx) + } else { + f.Magic = frameMagic + f.Descriptor.initW() + } + f.Blocks.initW(f, dst, num) + f.checksum.Reset() +} + +func (f *Frame) CloseW(dst io.Writer, num int) error { + if err := f.Blocks.close(f, num); err != nil { + return err + } + if f.isLegacy() { + return nil + } + buf := f.buf[:0] + // End mark (data block size of uint32(0)). + buf = append(buf, 0, 0, 0, 0) + if f.Descriptor.Flags.ContentChecksum() { + buf = f.checksum.Sum(buf) + } + _, err := dst.Write(buf) + return err +} + +func (f *Frame) isLegacy() bool { + return f.Magic == frameMagicLegacy +} + +func (f *Frame) ParseHeaders(src io.Reader) error { + if f.Magic > 0 { + // Header already read. + return nil + } + +newFrame: + var err error + if f.Magic, err = f.readUint32(src); err != nil { + return err + } + switch m := f.Magic; { + case m == frameMagic || m == frameMagicLegacy: + // All 16 values of frameSkipMagic are valid. + case m>>8 == frameSkipMagic>>8: + skip, err := f.readUint32(src) + if err != nil { + return err + } + if _, err := io.CopyN(ioutil.Discard, src, int64(skip)); err != nil { + return err + } + goto newFrame + default: + return lz4errors.ErrInvalidFrame + } + if err := f.Descriptor.initR(f, src); err != nil { + return err + } + f.checksum.Reset() + return nil +} + +func (f *Frame) InitR(src io.Reader, num int) (chan []byte, error) { + return f.Blocks.initR(f, num, src) +} + +func (f *Frame) CloseR(src io.Reader) (err error) { + if f.isLegacy() { + return nil + } + if !f.Descriptor.Flags.ContentChecksum() { + return nil + } + if f.Checksum, err = f.readUint32(src); err != nil { + return err + } + if c := f.checksum.Sum32(); c != f.Checksum { + return fmt.Errorf("%w: got %x; expected %x", lz4errors.ErrInvalidFrameChecksum, c, f.Checksum) + } + return nil +} + +type FrameDescriptor struct { + Flags DescriptorFlags + ContentSize uint64 + Checksum uint8 +} + +func (fd *FrameDescriptor) initW() { + fd.Flags.VersionSet(1) + fd.Flags.BlockIndependenceSet(true) +} + +func (fd *FrameDescriptor) Write(f *Frame, dst io.Writer) error { + if fd.Checksum > 0 { + // Header already written. + return nil + } + + buf := f.buf[:4] + // Write the magic number here even though it belongs to the Frame. + binary.LittleEndian.PutUint32(buf, f.Magic) + if !f.isLegacy() { + buf = buf[:4+2] + binary.LittleEndian.PutUint16(buf[4:], uint16(fd.Flags)) + + if fd.Flags.Size() { + buf = buf[:4+2+8] + binary.LittleEndian.PutUint64(buf[4+2:], fd.ContentSize) + } + fd.Checksum = descriptorChecksum(buf[4:]) + buf = append(buf, fd.Checksum) + } + + _, err := dst.Write(buf) + return err +} + +func (fd *FrameDescriptor) initR(f *Frame, src io.Reader) error { + if f.isLegacy() { + idx := lz4block.Index(lz4block.Block8Mb) + f.Descriptor.Flags.BlockSizeIndexSet(idx) + return nil + } + // Read the flags and the checksum, hoping that there is not content size. + buf := f.buf[:3] + if _, err := io.ReadFull(src, buf); err != nil { + return err + } + descr := binary.LittleEndian.Uint16(buf) + fd.Flags = DescriptorFlags(descr) + if fd.Flags.Size() { + // Append the 8 missing bytes. + buf = buf[:3+8] + if _, err := io.ReadFull(src, buf[3:]); err != nil { + return err + } + fd.ContentSize = binary.LittleEndian.Uint64(buf[2:]) + } + fd.Checksum = buf[len(buf)-1] // the checksum is the last byte + buf = buf[:len(buf)-1] // all descriptor fields except checksum + if c := descriptorChecksum(buf); fd.Checksum != c { + return fmt.Errorf("%w: got %x; expected %x", lz4errors.ErrInvalidHeaderChecksum, c, fd.Checksum) + } + // Validate the elements that can be. + if idx := fd.Flags.BlockSizeIndex(); !idx.IsValid() { + return lz4errors.ErrOptionInvalidBlockSize + } + return nil +} + +func descriptorChecksum(buf []byte) byte { + return byte(xxh32.ChecksumZero(buf) >> 8) +} diff --git a/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/frame_gen.go b/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/frame_gen.go new file mode 100644 index 000000000..d33a6be95 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/lz4stream/frame_gen.go @@ -0,0 +1,103 @@ +// Code generated by `gen.exe`. DO NOT EDIT. + +package lz4stream + +import "github.com/pierrec/lz4/v4/internal/lz4block" + +// DescriptorFlags is defined as follow: +// field bits +// ----- ---- +// _ 2 +// ContentChecksum 1 +// Size 1 +// BlockChecksum 1 +// BlockIndependence 1 +// Version 2 +// _ 4 +// BlockSizeIndex 3 +// _ 1 +type DescriptorFlags uint16 + +// Getters. +func (x DescriptorFlags) ContentChecksum() bool { return x>>2&1 != 0 } +func (x DescriptorFlags) Size() bool { return x>>3&1 != 0 } +func (x DescriptorFlags) BlockChecksum() bool { return x>>4&1 != 0 } +func (x DescriptorFlags) BlockIndependence() bool { return x>>5&1 != 0 } +func (x DescriptorFlags) Version() uint16 { return uint16(x >> 6 & 0x3) } +func (x DescriptorFlags) BlockSizeIndex() lz4block.BlockSizeIndex { + return lz4block.BlockSizeIndex(x >> 12 & 0x7) +} + +// Setters. +func (x *DescriptorFlags) ContentChecksumSet(v bool) *DescriptorFlags { + const b = 1 << 2 + if v { + *x = *x&^b | b + } else { + *x &^= b + } + return x +} +func (x *DescriptorFlags) SizeSet(v bool) *DescriptorFlags { + const b = 1 << 3 + if v { + *x = *x&^b | b + } else { + *x &^= b + } + return x +} +func (x *DescriptorFlags) BlockChecksumSet(v bool) *DescriptorFlags { + const b = 1 << 4 + if v { + *x = *x&^b | b + } else { + *x &^= b + } + return x +} +func (x *DescriptorFlags) BlockIndependenceSet(v bool) *DescriptorFlags { + const b = 1 << 5 + if v { + *x = *x&^b | b + } else { + *x &^= b + } + return x +} +func (x *DescriptorFlags) VersionSet(v uint16) *DescriptorFlags { + *x = *x&^(0x3<<6) | (DescriptorFlags(v) & 0x3 << 6) + return x +} +func (x *DescriptorFlags) BlockSizeIndexSet(v lz4block.BlockSizeIndex) *DescriptorFlags { + *x = *x&^(0x7<<12) | (DescriptorFlags(v) & 0x7 << 12) + return x +} + +// Code generated by `gen.exe`. DO NOT EDIT. + +// DataBlockSize is defined as follow: +// field bits +// ----- ---- +// size 31 +// Uncompressed 1 +type DataBlockSize uint32 + +// Getters. +func (x DataBlockSize) size() int { return int(x & 0x7FFFFFFF) } +func (x DataBlockSize) Uncompressed() bool { return x>>31&1 != 0 } + +// Setters. +func (x *DataBlockSize) sizeSet(v int) *DataBlockSize { + *x = *x&^0x7FFFFFFF | DataBlockSize(v)&0x7FFFFFFF + return x +} +func (x *DataBlockSize) UncompressedSet(v bool) *DataBlockSize { + const b = 1 << 31 + if v { + *x = *x&^b | b + } else { + *x &^= b + } + return x +} diff --git a/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero.go b/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero.go new file mode 100644 index 000000000..651d10c10 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero.go @@ -0,0 +1,212 @@ +// Package xxh32 implements the very fast XXH hashing algorithm (32 bits version). +// (ported from the reference implementation https://github.com/Cyan4973/xxHash/) +package xxh32 + +import ( + "encoding/binary" +) + +const ( + prime1 uint32 = 2654435761 + prime2 uint32 = 2246822519 + prime3 uint32 = 3266489917 + prime4 uint32 = 668265263 + prime5 uint32 = 374761393 + + primeMask = 0xFFFFFFFF + prime1plus2 = uint32((uint64(prime1) + uint64(prime2)) & primeMask) // 606290984 + prime1minus = uint32((-int64(prime1)) & primeMask) // 1640531535 +) + +// XXHZero represents an xxhash32 object with seed 0. +type XXHZero struct { + v [4]uint32 + totalLen uint64 + buf [16]byte + bufused int +} + +// Sum appends the current hash to b and returns the resulting slice. +// It does not change the underlying hash state. +func (xxh XXHZero) Sum(b []byte) []byte { + h32 := xxh.Sum32() + return append(b, byte(h32), byte(h32>>8), byte(h32>>16), byte(h32>>24)) +} + +// Reset resets the Hash to its initial state. +func (xxh *XXHZero) Reset() { + xxh.v[0] = prime1plus2 + xxh.v[1] = prime2 + xxh.v[2] = 0 + xxh.v[3] = prime1minus + xxh.totalLen = 0 + xxh.bufused = 0 +} + +// Size returns the number of bytes returned by Sum(). +func (xxh *XXHZero) Size() int { + return 4 +} + +// BlockSizeIndex gives the minimum number of bytes accepted by Write(). +func (xxh *XXHZero) BlockSize() int { + return 1 +} + +// Write adds input bytes to the Hash. +// It never returns an error. +func (xxh *XXHZero) Write(input []byte) (int, error) { + if xxh.totalLen == 0 { + xxh.Reset() + } + n := len(input) + m := xxh.bufused + + xxh.totalLen += uint64(n) + + r := len(xxh.buf) - m + if n < r { + copy(xxh.buf[m:], input) + xxh.bufused += len(input) + return n, nil + } + + var buf *[16]byte + if m != 0 { + // some data left from previous update + buf = &xxh.buf + c := copy(buf[m:], input) + n -= c + input = input[c:] + } + update(&xxh.v, buf, input) + xxh.bufused = copy(xxh.buf[:], input[n-n%16:]) + + return n, nil +} + +// Portable version of update. This updates v by processing all of buf +// (if not nil) and all full 16-byte blocks of input. +func updateGo(v *[4]uint32, buf *[16]byte, input []byte) { + // Causes compiler to work directly from registers instead of stack: + v1, v2, v3, v4 := v[0], v[1], v[2], v[3] + + if buf != nil { + v1 = rol13(v1+binary.LittleEndian.Uint32(buf[:])*prime2) * prime1 + v2 = rol13(v2+binary.LittleEndian.Uint32(buf[4:])*prime2) * prime1 + v3 = rol13(v3+binary.LittleEndian.Uint32(buf[8:])*prime2) * prime1 + v4 = rol13(v4+binary.LittleEndian.Uint32(buf[12:])*prime2) * prime1 + } + + for ; len(input) >= 16; input = input[16:] { + sub := input[:16] //BCE hint for compiler + v1 = rol13(v1+binary.LittleEndian.Uint32(sub[:])*prime2) * prime1 + v2 = rol13(v2+binary.LittleEndian.Uint32(sub[4:])*prime2) * prime1 + v3 = rol13(v3+binary.LittleEndian.Uint32(sub[8:])*prime2) * prime1 + v4 = rol13(v4+binary.LittleEndian.Uint32(sub[12:])*prime2) * prime1 + } + v[0], v[1], v[2], v[3] = v1, v2, v3, v4 +} + +// Sum32 returns the 32 bits Hash value. +func (xxh *XXHZero) Sum32() uint32 { + h32 := uint32(xxh.totalLen) + if h32 >= 16 { + h32 += rol1(xxh.v[0]) + rol7(xxh.v[1]) + rol12(xxh.v[2]) + rol18(xxh.v[3]) + } else { + h32 += prime5 + } + + p := 0 + n := xxh.bufused + buf := xxh.buf + for n := n - 4; p <= n; p += 4 { + h32 += binary.LittleEndian.Uint32(buf[p:p+4]) * prime3 + h32 = rol17(h32) * prime4 + } + for ; p < n; p++ { + h32 += uint32(buf[p]) * prime5 + h32 = rol11(h32) * prime1 + } + + h32 ^= h32 >> 15 + h32 *= prime2 + h32 ^= h32 >> 13 + h32 *= prime3 + h32 ^= h32 >> 16 + + return h32 +} + +// Portable version of ChecksumZero. +func checksumZeroGo(input []byte) uint32 { + n := len(input) + h32 := uint32(n) + + if n < 16 { + h32 += prime5 + } else { + v1 := prime1plus2 + v2 := prime2 + v3 := uint32(0) + v4 := prime1minus + p := 0 + for n := n - 16; p <= n; p += 16 { + sub := input[p:][:16] //BCE hint for compiler + v1 = rol13(v1+binary.LittleEndian.Uint32(sub[:])*prime2) * prime1 + v2 = rol13(v2+binary.LittleEndian.Uint32(sub[4:])*prime2) * prime1 + v3 = rol13(v3+binary.LittleEndian.Uint32(sub[8:])*prime2) * prime1 + v4 = rol13(v4+binary.LittleEndian.Uint32(sub[12:])*prime2) * prime1 + } + input = input[p:] + n -= p + h32 += rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4) + } + + p := 0 + for n := n - 4; p <= n; p += 4 { + h32 += binary.LittleEndian.Uint32(input[p:p+4]) * prime3 + h32 = rol17(h32) * prime4 + } + for p < n { + h32 += uint32(input[p]) * prime5 + h32 = rol11(h32) * prime1 + p++ + } + + h32 ^= h32 >> 15 + h32 *= prime2 + h32 ^= h32 >> 13 + h32 *= prime3 + h32 ^= h32 >> 16 + + return h32 +} + +func rol1(u uint32) uint32 { + return u<<1 | u>>31 +} + +func rol7(u uint32) uint32 { + return u<<7 | u>>25 +} + +func rol11(u uint32) uint32 { + return u<<11 | u>>21 +} + +func rol12(u uint32) uint32 { + return u<<12 | u>>20 +} + +func rol13(u uint32) uint32 { + return u<<13 | u>>19 +} + +func rol17(u uint32) uint32 { + return u<<17 | u>>15 +} + +func rol18(u uint32) uint32 { + return u<<18 | u>>14 +} diff --git a/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_arm.go b/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_arm.go new file mode 100644 index 000000000..0978b2665 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_arm.go @@ -0,0 +1,11 @@ +// +build !noasm + +package xxh32 + +// ChecksumZero returns the 32-bit hash of input. +// +//go:noescape +func ChecksumZero(input []byte) uint32 + +//go:noescape +func update(v *[4]uint32, buf *[16]byte, input []byte) diff --git a/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_arm.s b/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_arm.s new file mode 100644 index 000000000..c18ffd574 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_arm.s @@ -0,0 +1,251 @@ +// +build !noasm + +#include "go_asm.h" +#include "textflag.h" + +// Register allocation. +#define p R0 +#define n R1 +#define h R2 +#define v1 R2 // Alias for h. +#define v2 R3 +#define v3 R4 +#define v4 R5 +#define x1 R6 +#define x2 R7 +#define x3 R8 +#define x4 R9 + +// We need the primes in registers. The 16-byte loop only uses prime{1,2}. +#define prime1r R11 +#define prime2r R12 +#define prime3r R3 // The rest can alias v{2-4}. +#define prime4r R4 +#define prime5r R5 + +// Update round macros. These read from and increment p. + +#define round16aligned \ + MOVM.IA.W (p), [x1, x2, x3, x4] \ + \ + MULA x1, prime2r, v1, v1 \ + MULA x2, prime2r, v2, v2 \ + MULA x3, prime2r, v3, v3 \ + MULA x4, prime2r, v4, v4 \ + \ + MOVW v1 @> 19, v1 \ + MOVW v2 @> 19, v2 \ + MOVW v3 @> 19, v3 \ + MOVW v4 @> 19, v4 \ + \ + MUL prime1r, v1 \ + MUL prime1r, v2 \ + MUL prime1r, v3 \ + MUL prime1r, v4 \ + +#define round16unaligned \ + MOVBU.P 16(p), x1 \ + MOVBU -15(p), x2 \ + ORR x2 << 8, x1 \ + MOVBU -14(p), x3 \ + MOVBU -13(p), x4 \ + ORR x4 << 8, x3 \ + ORR x3 << 16, x1 \ + \ + MULA x1, prime2r, v1, v1 \ + MOVW v1 @> 19, v1 \ + MUL prime1r, v1 \ + \ + MOVBU -12(p), x1 \ + MOVBU -11(p), x2 \ + ORR x2 << 8, x1 \ + MOVBU -10(p), x3 \ + MOVBU -9(p), x4 \ + ORR x4 << 8, x3 \ + ORR x3 << 16, x1 \ + \ + MULA x1, prime2r, v2, v2 \ + MOVW v2 @> 19, v2 \ + MUL prime1r, v2 \ + \ + MOVBU -8(p), x1 \ + MOVBU -7(p), x2 \ + ORR x2 << 8, x1 \ + MOVBU -6(p), x3 \ + MOVBU -5(p), x4 \ + ORR x4 << 8, x3 \ + ORR x3 << 16, x1 \ + \ + MULA x1, prime2r, v3, v3 \ + MOVW v3 @> 19, v3 \ + MUL prime1r, v3 \ + \ + MOVBU -4(p), x1 \ + MOVBU -3(p), x2 \ + ORR x2 << 8, x1 \ + MOVBU -2(p), x3 \ + MOVBU -1(p), x4 \ + ORR x4 << 8, x3 \ + ORR x3 << 16, x1 \ + \ + MULA x1, prime2r, v4, v4 \ + MOVW v4 @> 19, v4 \ + MUL prime1r, v4 \ + + +// func ChecksumZero([]byte) uint32 +TEXT ·ChecksumZero(SB), NOFRAME|NOSPLIT, $-4-16 + MOVW input_base+0(FP), p + MOVW input_len+4(FP), n + + MOVW $const_prime1, prime1r + MOVW $const_prime2, prime2r + + // Set up h for n < 16. It's tempting to say {ADD prime5, n, h} + // here, but that's a pseudo-op that generates a load through R11. + MOVW $const_prime5, prime5r + ADD prime5r, n, h + CMP $0, n + BEQ end + + // We let n go negative so we can do comparisons with SUB.S + // instead of separate CMP. + SUB.S $16, n + BMI loop16done + + ADD prime1r, prime2r, v1 + MOVW prime2r, v2 + MOVW $0, v3 + RSB $0, prime1r, v4 + + TST $3, p + BNE loop16unaligned + +loop16aligned: + SUB.S $16, n + round16aligned + BPL loop16aligned + B loop16finish + +loop16unaligned: + SUB.S $16, n + round16unaligned + BPL loop16unaligned + +loop16finish: + MOVW v1 @> 31, h + ADD v2 @> 25, h + ADD v3 @> 20, h + ADD v4 @> 14, h + + // h += len(input) with v2 as temporary. + MOVW input_len+4(FP), v2 + ADD v2, h + +loop16done: + ADD $16, n // Restore number of bytes left. + + SUB.S $4, n + MOVW $const_prime3, prime3r + BMI loop4done + MOVW $const_prime4, prime4r + + TST $3, p + BNE loop4unaligned + +loop4aligned: + SUB.S $4, n + + MOVW.P 4(p), x1 + MULA prime3r, x1, h, h + MOVW h @> 15, h + MUL prime4r, h + + BPL loop4aligned + B loop4done + +loop4unaligned: + SUB.S $4, n + + MOVBU.P 4(p), x1 + MOVBU -3(p), x2 + ORR x2 << 8, x1 + MOVBU -2(p), x3 + ORR x3 << 16, x1 + MOVBU -1(p), x4 + ORR x4 << 24, x1 + + MULA prime3r, x1, h, h + MOVW h @> 15, h + MUL prime4r, h + + BPL loop4unaligned + +loop4done: + ADD.S $4, n // Restore number of bytes left. + BEQ end + + MOVW $const_prime5, prime5r + +loop1: + SUB.S $1, n + + MOVBU.P 1(p), x1 + MULA prime5r, x1, h, h + MOVW h @> 21, h + MUL prime1r, h + + BNE loop1 + +end: + MOVW $const_prime3, prime3r + EOR h >> 15, h + MUL prime2r, h + EOR h >> 13, h + MUL prime3r, h + EOR h >> 16, h + + MOVW h, ret+12(FP) + RET + + +// func update(v *[4]uint64, buf *[16]byte, p []byte) +TEXT ·update(SB), NOFRAME|NOSPLIT, $-4-20 + MOVW v+0(FP), p + MOVM.IA (p), [v1, v2, v3, v4] + + MOVW $const_prime1, prime1r + MOVW $const_prime2, prime2r + + // Process buf, if not nil. + MOVW buf+4(FP), p + CMP $0, p + BEQ noBuffered + + round16aligned + +noBuffered: + MOVW input_base +8(FP), p + MOVW input_len +12(FP), n + + SUB.S $16, n + BMI end + + TST $3, p + BNE loop16unaligned + +loop16aligned: + SUB.S $16, n + round16aligned + BPL loop16aligned + B end + +loop16unaligned: + SUB.S $16, n + round16unaligned + BPL loop16unaligned + +end: + MOVW v+0(FP), p + MOVM.IA [v1, v2, v3, v4], (p) + RET diff --git a/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_other.go b/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_other.go new file mode 100644 index 000000000..c96b59b8c --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/internal/xxh32/xxh32zero_other.go @@ -0,0 +1,10 @@ +// +build !arm noasm + +package xxh32 + +// ChecksumZero returns the 32-bit hash of input. +func ChecksumZero(input []byte) uint32 { return checksumZeroGo(input) } + +func update(v *[4]uint32, buf *[16]byte, input []byte) { + updateGo(v, buf, input) +} diff --git a/vendor/github.com/pierrec/lz4/v4/lz4.go b/vendor/github.com/pierrec/lz4/v4/lz4.go new file mode 100644 index 000000000..a62022e08 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/lz4.go @@ -0,0 +1,157 @@ +// Package lz4 implements reading and writing lz4 compressed data. +// +// The package supports both the LZ4 stream format, +// as specified in http://fastcompression.blogspot.fr/2013/04/lz4-streaming-format-final.html, +// and the LZ4 block format, defined at +// http://fastcompression.blogspot.fr/2011/05/lz4-explained.html. +// +// See https://github.com/lz4/lz4 for the reference C implementation. +package lz4 + +import ( + "github.com/pierrec/lz4/v4/internal/lz4block" + "github.com/pierrec/lz4/v4/internal/lz4errors" +) + +func _() { + // Safety checks for duplicated elements. + var x [1]struct{} + _ = x[lz4block.CompressionLevel(Fast)-lz4block.Fast] + _ = x[Block64Kb-BlockSize(lz4block.Block64Kb)] + _ = x[Block256Kb-BlockSize(lz4block.Block256Kb)] + _ = x[Block1Mb-BlockSize(lz4block.Block1Mb)] + _ = x[Block4Mb-BlockSize(lz4block.Block4Mb)] +} + +// CompressBlockBound returns the maximum size of a given buffer of size n, when not compressible. +func CompressBlockBound(n int) int { + return lz4block.CompressBlockBound(n) +} + +// UncompressBlock uncompresses the source buffer into the destination one, +// and returns the uncompressed size. +// +// The destination buffer must be sized appropriately. +// +// An error is returned if the source data is invalid or the destination buffer is too small. +func UncompressBlock(src, dst []byte) (int, error) { + return lz4block.UncompressBlock(src, dst, nil) +} + +// UncompressBlockWithDict uncompresses the source buffer into the destination one using a +// dictionary, and returns the uncompressed size. +// +// The destination buffer must be sized appropriately. +// +// An error is returned if the source data is invalid or the destination buffer is too small. +func UncompressBlockWithDict(src, dst, dict []byte) (int, error) { + return lz4block.UncompressBlock(src, dst, dict) +} + +// A Compressor compresses data into the LZ4 block format. +// It uses a fast compression algorithm. +// +// A Compressor is not safe for concurrent use by multiple goroutines. +// +// Use a Writer to compress into the LZ4 stream format. +type Compressor struct{ c lz4block.Compressor } + +// CompressBlock compresses the source buffer src into the destination dst. +// +// If compression is successful, the first return value is the size of the +// compressed data, which is always >0. +// +// If dst has length at least CompressBlockBound(len(src)), compression always +// succeeds. Otherwise, the first return value is zero. The error return is +// non-nil if the compressed data does not fit in dst, but it might fit in a +// larger buffer that is still smaller than CompressBlockBound(len(src)). The +// return value (0, nil) means the data is likely incompressible and a buffer +// of length CompressBlockBound(len(src)) should be passed in. +func (c *Compressor) CompressBlock(src, dst []byte) (int, error) { + return c.c.CompressBlock(src, dst) +} + +// CompressBlock compresses the source buffer into the destination one. +// This is the fast version of LZ4 compression and also the default one. +// +// The argument hashTable is scratch space for a hash table used by the +// compressor. If provided, it should have length at least 1<<16. If it is +// shorter (or nil), CompressBlock allocates its own hash table. +// +// The size of the compressed data is returned. +// +// If the destination buffer size is lower than CompressBlockBound and +// the compressed size is 0 and no error, then the data is incompressible. +// +// An error is returned if the destination buffer is too small. + +// CompressBlock is equivalent to Compressor.CompressBlock. +// The final argument is ignored and should be set to nil. +// +// This function is deprecated. Use a Compressor instead. +func CompressBlock(src, dst []byte, _ []int) (int, error) { + return lz4block.CompressBlock(src, dst) +} + +// A CompressorHC compresses data into the LZ4 block format. +// Its compression ratio is potentially better than that of a Compressor, +// but it is also slower and requires more memory. +// +// A Compressor is not safe for concurrent use by multiple goroutines. +// +// Use a Writer to compress into the LZ4 stream format. +type CompressorHC struct { + // Level is the maximum search depth for compression. + // Values <= 0 mean no maximum. + Level CompressionLevel + c lz4block.CompressorHC +} + +// CompressBlock compresses the source buffer src into the destination dst. +// +// If compression is successful, the first return value is the size of the +// compressed data, which is always >0. +// +// If dst has length at least CompressBlockBound(len(src)), compression always +// succeeds. Otherwise, the first return value is zero. The error return is +// non-nil if the compressed data does not fit in dst, but it might fit in a +// larger buffer that is still smaller than CompressBlockBound(len(src)). The +// return value (0, nil) means the data is likely incompressible and a buffer +// of length CompressBlockBound(len(src)) should be passed in. +func (c *CompressorHC) CompressBlock(src, dst []byte) (int, error) { + return c.c.CompressBlock(src, dst, lz4block.CompressionLevel(c.Level)) +} + +// CompressBlockHC is equivalent to CompressorHC.CompressBlock. +// The final two arguments are ignored and should be set to nil. +// +// This function is deprecated. Use a CompressorHC instead. +func CompressBlockHC(src, dst []byte, depth CompressionLevel, _, _ []int) (int, error) { + return lz4block.CompressBlockHC(src, dst, lz4block.CompressionLevel(depth)) +} + +const ( + // ErrInvalidSourceShortBuffer is returned by UncompressBlock or CompressBLock when a compressed + // block is corrupted or the destination buffer is not large enough for the uncompressed data. + ErrInvalidSourceShortBuffer = lz4errors.ErrInvalidSourceShortBuffer + // ErrInvalidFrame is returned when reading an invalid LZ4 archive. + ErrInvalidFrame = lz4errors.ErrInvalidFrame + // ErrInternalUnhandledState is an internal error. + ErrInternalUnhandledState = lz4errors.ErrInternalUnhandledState + // ErrInvalidHeaderChecksum is returned when reading a frame. + ErrInvalidHeaderChecksum = lz4errors.ErrInvalidHeaderChecksum + // ErrInvalidBlockChecksum is returned when reading a frame. + ErrInvalidBlockChecksum = lz4errors.ErrInvalidBlockChecksum + // ErrInvalidFrameChecksum is returned when reading a frame. + ErrInvalidFrameChecksum = lz4errors.ErrInvalidFrameChecksum + // ErrOptionInvalidCompressionLevel is returned when the supplied compression level is invalid. + ErrOptionInvalidCompressionLevel = lz4errors.ErrOptionInvalidCompressionLevel + // ErrOptionClosedOrError is returned when an option is applied to a closed or in error object. + ErrOptionClosedOrError = lz4errors.ErrOptionClosedOrError + // ErrOptionInvalidBlockSize is returned when + ErrOptionInvalidBlockSize = lz4errors.ErrOptionInvalidBlockSize + // ErrOptionNotApplicable is returned when trying to apply an option to an object not supporting it. + ErrOptionNotApplicable = lz4errors.ErrOptionNotApplicable + // ErrWriterNotClosed is returned when attempting to reset an unclosed writer. + ErrWriterNotClosed = lz4errors.ErrWriterNotClosed +) diff --git a/vendor/github.com/pierrec/lz4/v4/options.go b/vendor/github.com/pierrec/lz4/v4/options.go new file mode 100644 index 000000000..57a44e767 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/options.go @@ -0,0 +1,242 @@ +package lz4 + +import ( + "fmt" + "reflect" + "runtime" + + "github.com/pierrec/lz4/v4/internal/lz4block" + "github.com/pierrec/lz4/v4/internal/lz4errors" +) + +//go:generate go run golang.org/x/tools/cmd/stringer -type=BlockSize,CompressionLevel -output options_gen.go + +type ( + applier interface { + Apply(...Option) error + private() + } + // Option defines the parameters to setup an LZ4 Writer or Reader. + Option func(applier) error +) + +// String returns a string representation of the option with its parameter(s). +func (o Option) String() string { + return o(nil).Error() +} + +// Default options. +var ( + DefaultBlockSizeOption = BlockSizeOption(Block4Mb) + DefaultChecksumOption = ChecksumOption(true) + DefaultConcurrency = ConcurrencyOption(1) + defaultOnBlockDone = OnBlockDoneOption(nil) +) + +const ( + Block64Kb BlockSize = 1 << (16 + iota*2) + Block256Kb + Block1Mb + Block4Mb +) + +// BlockSizeIndex defines the size of the blocks to be compressed. +type BlockSize uint32 + +// BlockSizeOption defines the maximum size of compressed blocks (default=Block4Mb). +func BlockSizeOption(size BlockSize) Option { + return func(a applier) error { + switch w := a.(type) { + case nil: + s := fmt.Sprintf("BlockSizeOption(%s)", size) + return lz4errors.Error(s) + case *Writer: + size := uint32(size) + if !lz4block.IsValid(size) { + return fmt.Errorf("%w: %d", lz4errors.ErrOptionInvalidBlockSize, size) + } + w.frame.Descriptor.Flags.BlockSizeIndexSet(lz4block.Index(size)) + return nil + case *CompressingReader: + size := uint32(size) + if !lz4block.IsValid(size) { + return fmt.Errorf("%w: %d", lz4errors.ErrOptionInvalidBlockSize, size) + } + w.frame.Descriptor.Flags.BlockSizeIndexSet(lz4block.Index(size)) + return nil + } + return lz4errors.ErrOptionNotApplicable + } +} + +// BlockChecksumOption enables or disables block checksum (default=false). +func BlockChecksumOption(flag bool) Option { + return func(a applier) error { + switch w := a.(type) { + case nil: + s := fmt.Sprintf("BlockChecksumOption(%v)", flag) + return lz4errors.Error(s) + case *Writer: + w.frame.Descriptor.Flags.BlockChecksumSet(flag) + return nil + case *CompressingReader: + w.frame.Descriptor.Flags.BlockChecksumSet(flag) + return nil + } + return lz4errors.ErrOptionNotApplicable + } +} + +// ChecksumOption enables/disables all blocks or content checksum (default=true). +func ChecksumOption(flag bool) Option { + return func(a applier) error { + switch w := a.(type) { + case nil: + s := fmt.Sprintf("ChecksumOption(%v)", flag) + return lz4errors.Error(s) + case *Writer: + w.frame.Descriptor.Flags.ContentChecksumSet(flag) + return nil + case *CompressingReader: + w.frame.Descriptor.Flags.ContentChecksumSet(flag) + return nil + } + return lz4errors.ErrOptionNotApplicable + } +} + +// SizeOption sets the size of the original uncompressed data (default=0). It is useful to know the size of the +// whole uncompressed data stream. +func SizeOption(size uint64) Option { + return func(a applier) error { + switch w := a.(type) { + case nil: + s := fmt.Sprintf("SizeOption(%d)", size) + return lz4errors.Error(s) + case *Writer: + w.frame.Descriptor.Flags.SizeSet(size > 0) + w.frame.Descriptor.ContentSize = size + return nil + case *CompressingReader: + w.frame.Descriptor.Flags.SizeSet(size > 0) + w.frame.Descriptor.ContentSize = size + return nil + } + return lz4errors.ErrOptionNotApplicable + } +} + +// ConcurrencyOption sets the number of go routines used for compression. +// If n <= 0, then the output of runtime.GOMAXPROCS(0) is used. +func ConcurrencyOption(n int) Option { + if n <= 0 { + n = runtime.GOMAXPROCS(0) + } + return func(a applier) error { + switch rw := a.(type) { + case nil: + s := fmt.Sprintf("ConcurrencyOption(%d)", n) + return lz4errors.Error(s) + case *Writer: + rw.num = n + return nil + case *Reader: + rw.num = n + return nil + } + return lz4errors.ErrOptionNotApplicable + } +} + +// CompressionLevel defines the level of compression to use. The higher the better, but slower, compression. +type CompressionLevel uint32 + +const ( + Fast CompressionLevel = 0 + Level1 CompressionLevel = 1 << (8 + iota) + Level2 + Level3 + Level4 + Level5 + Level6 + Level7 + Level8 + Level9 +) + +// CompressionLevelOption defines the compression level (default=Fast). +func CompressionLevelOption(level CompressionLevel) Option { + return func(a applier) error { + switch w := a.(type) { + case nil: + s := fmt.Sprintf("CompressionLevelOption(%s)", level) + return lz4errors.Error(s) + case *Writer: + switch level { + case Fast, Level1, Level2, Level3, Level4, Level5, Level6, Level7, Level8, Level9: + default: + return fmt.Errorf("%w: %d", lz4errors.ErrOptionInvalidCompressionLevel, level) + } + w.level = lz4block.CompressionLevel(level) + return nil + case *CompressingReader: + switch level { + case Fast, Level1, Level2, Level3, Level4, Level5, Level6, Level7, Level8, Level9: + default: + return fmt.Errorf("%w: %d", lz4errors.ErrOptionInvalidCompressionLevel, level) + } + w.level = lz4block.CompressionLevel(level) + return nil + } + return lz4errors.ErrOptionNotApplicable + } +} + +func onBlockDone(int) {} + +// OnBlockDoneOption is triggered when a block has been processed. For a Writer, it is when is has been compressed, +// for a Reader, it is when it has been uncompressed. +func OnBlockDoneOption(handler func(size int)) Option { + if handler == nil { + handler = onBlockDone + } + return func(a applier) error { + switch rw := a.(type) { + case nil: + s := fmt.Sprintf("OnBlockDoneOption(%s)", reflect.TypeOf(handler).String()) + return lz4errors.Error(s) + case *Writer: + rw.handler = handler + return nil + case *Reader: + rw.handler = handler + return nil + case *CompressingReader: + rw.handler = handler + return nil + } + return lz4errors.ErrOptionNotApplicable + } +} + +// LegacyOption provides support for writing LZ4 frames in the legacy format. +// +// See https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md#legacy-frame. +// +// NB. compressed Linux kernel images use a tweaked LZ4 legacy format where +// the compressed stream is followed by the original (uncompressed) size of +// the kernel (https://events.static.linuxfound.org/sites/events/files/lcjpcojp13_klee.pdf). +// This is also supported as a special case. +func LegacyOption(legacy bool) Option { + return func(a applier) error { + switch rw := a.(type) { + case nil: + s := fmt.Sprintf("LegacyOption(%v)", legacy) + return lz4errors.Error(s) + case *Writer: + rw.legacy = legacy + return nil + } + return lz4errors.ErrOptionNotApplicable + } +} diff --git a/vendor/github.com/pierrec/lz4/v4/options_gen.go b/vendor/github.com/pierrec/lz4/v4/options_gen.go new file mode 100644 index 000000000..2de814909 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/options_gen.go @@ -0,0 +1,92 @@ +// Code generated by "stringer -type=BlockSize,CompressionLevel -output options_gen.go"; DO NOT EDIT. + +package lz4 + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Block64Kb-65536] + _ = x[Block256Kb-262144] + _ = x[Block1Mb-1048576] + _ = x[Block4Mb-4194304] +} + +const ( + _BlockSize_name_0 = "Block64Kb" + _BlockSize_name_1 = "Block256Kb" + _BlockSize_name_2 = "Block1Mb" + _BlockSize_name_3 = "Block4Mb" +) + +func (i BlockSize) String() string { + switch { + case i == 65536: + return _BlockSize_name_0 + case i == 262144: + return _BlockSize_name_1 + case i == 1048576: + return _BlockSize_name_2 + case i == 4194304: + return _BlockSize_name_3 + default: + return "BlockSize(" + strconv.FormatInt(int64(i), 10) + ")" + } +} +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[Fast-0] + _ = x[Level1-512] + _ = x[Level2-1024] + _ = x[Level3-2048] + _ = x[Level4-4096] + _ = x[Level5-8192] + _ = x[Level6-16384] + _ = x[Level7-32768] + _ = x[Level8-65536] + _ = x[Level9-131072] +} + +const ( + _CompressionLevel_name_0 = "Fast" + _CompressionLevel_name_1 = "Level1" + _CompressionLevel_name_2 = "Level2" + _CompressionLevel_name_3 = "Level3" + _CompressionLevel_name_4 = "Level4" + _CompressionLevel_name_5 = "Level5" + _CompressionLevel_name_6 = "Level6" + _CompressionLevel_name_7 = "Level7" + _CompressionLevel_name_8 = "Level8" + _CompressionLevel_name_9 = "Level9" +) + +func (i CompressionLevel) String() string { + switch { + case i == 0: + return _CompressionLevel_name_0 + case i == 512: + return _CompressionLevel_name_1 + case i == 1024: + return _CompressionLevel_name_2 + case i == 2048: + return _CompressionLevel_name_3 + case i == 4096: + return _CompressionLevel_name_4 + case i == 8192: + return _CompressionLevel_name_5 + case i == 16384: + return _CompressionLevel_name_6 + case i == 32768: + return _CompressionLevel_name_7 + case i == 65536: + return _CompressionLevel_name_8 + case i == 131072: + return _CompressionLevel_name_9 + default: + return "CompressionLevel(" + strconv.FormatInt(int64(i), 10) + ")" + } +} diff --git a/vendor/github.com/pierrec/lz4/v4/reader.go b/vendor/github.com/pierrec/lz4/v4/reader.go new file mode 100644 index 000000000..275daad7c --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/reader.go @@ -0,0 +1,275 @@ +package lz4 + +import ( + "bytes" + "io" + + "github.com/pierrec/lz4/v4/internal/lz4block" + "github.com/pierrec/lz4/v4/internal/lz4errors" + "github.com/pierrec/lz4/v4/internal/lz4stream" +) + +var readerStates = []aState{ + noState: newState, + errorState: newState, + newState: readState, + readState: closedState, + closedState: newState, +} + +// NewReader returns a new LZ4 frame decoder. +func NewReader(r io.Reader) *Reader { + return newReader(r, false) +} + +func newReader(r io.Reader, legacy bool) *Reader { + zr := &Reader{frame: lz4stream.NewFrame()} + zr.state.init(readerStates) + _ = zr.Apply(DefaultConcurrency, defaultOnBlockDone) + zr.Reset(r) + return zr +} + +// Reader allows reading an LZ4 stream. +type Reader struct { + state _State + src io.Reader // source reader + num int // concurrency level + frame *lz4stream.Frame // frame being read + data []byte // block buffer allocated in non concurrent mode + reads chan []byte // pending data + idx int // size of pending data + handler func(int) + cum uint32 + dict []byte +} + +func (*Reader) private() {} + +func (r *Reader) Apply(options ...Option) (err error) { + defer r.state.check(&err) + switch r.state.state { + case newState: + case errorState: + return r.state.err + default: + return lz4errors.ErrOptionClosedOrError + } + for _, o := range options { + if err = o(r); err != nil { + return + } + } + return +} + +// Size returns the size of the underlying uncompressed data, if set in the stream. +func (r *Reader) Size() int { + switch r.state.state { + case readState, closedState: + if r.frame.Descriptor.Flags.Size() { + return int(r.frame.Descriptor.ContentSize) + } + } + return 0 +} + +func (r *Reader) isNotConcurrent() bool { + return r.num == 1 +} + +func (r *Reader) init() error { + err := r.frame.ParseHeaders(r.src) + if err != nil { + return err + } + if !r.frame.Descriptor.Flags.BlockIndependence() { + // We can't decompress dependent blocks concurrently. + // Instead of throwing an error to the user, silently drop concurrency + r.num = 1 + } + data, err := r.frame.InitR(r.src, r.num) + if err != nil { + return err + } + r.reads = data + r.idx = 0 + size := r.frame.Descriptor.Flags.BlockSizeIndex() + r.data = size.Get() + r.cum = 0 + return nil +} + +func (r *Reader) Read(buf []byte) (n int, err error) { + defer r.state.check(&err) + switch r.state.state { + case readState: + case closedState, errorState: + return 0, r.state.err + case newState: + // First initialization. + if err = r.init(); r.state.next(err) { + return + } + default: + return 0, r.state.fail() + } + for len(buf) > 0 { + var bn int + if r.idx == 0 { + if r.isNotConcurrent() { + bn, err = r.read(buf) + } else { + lz4block.Put(r.data) + r.data = <-r.reads + if len(r.data) == 0 { + // No uncompressed data: something went wrong or we are done. + err = r.frame.Blocks.ErrorR() + } + } + switch err { + case nil: + case io.EOF: + if er := r.frame.CloseR(r.src); er != nil { + err = er + } + lz4block.Put(r.data) + r.data = nil + return + default: + return + } + } + if bn == 0 { + // Fill buf with buffered data. + bn = copy(buf, r.data[r.idx:]) + r.idx += bn + if r.idx == len(r.data) { + // All data read, get ready for the next Read. + r.idx = 0 + } + } + buf = buf[bn:] + n += bn + r.handler(bn) + } + return +} + +// read uncompresses the next block as follow: +// - if buf has enough room, the block is uncompressed into it directly +// and the lenght of used space is returned +// - else, the uncompress data is stored in r.data and 0 is returned +func (r *Reader) read(buf []byte) (int, error) { + block := r.frame.Blocks.Block + _, err := block.Read(r.frame, r.src, r.cum) + if err != nil { + return 0, err + } + var direct bool + dst := r.data[:cap(r.data)] + if len(buf) >= len(dst) { + // Uncompress directly into buf. + direct = true + dst = buf + } + dst, err = block.Uncompress(r.frame, dst, r.dict, true) + if err != nil { + return 0, err + } + if !r.frame.Descriptor.Flags.BlockIndependence() { + if len(r.dict)+len(dst) > 128*1024 { + preserveSize := 64*1024 - len(dst) + if preserveSize < 0 { + preserveSize = 0 + } + r.dict = r.dict[len(r.dict)-preserveSize:] + } + r.dict = append(r.dict, dst...) + } + r.cum += uint32(len(dst)) + if direct { + return len(dst), nil + } + r.data = dst + return 0, nil +} + +// Reset clears the state of the Reader r such that it is equivalent to its +// initial state from NewReader, but instead reading from reader. +// No access to reader is performed. +func (r *Reader) Reset(reader io.Reader) { + if r.data != nil { + lz4block.Put(r.data) + r.data = nil + } + r.frame.Reset(r.num) + r.state.reset() + r.src = reader + r.reads = nil +} + +// WriteTo efficiently uncompresses the data from the Reader underlying source to w. +func (r *Reader) WriteTo(w io.Writer) (n int64, err error) { + switch r.state.state { + case closedState, errorState: + return 0, r.state.err + case newState: + if err = r.init(); r.state.next(err) { + return + } + default: + return 0, r.state.fail() + } + defer r.state.nextd(&err) + + var data []byte + if r.isNotConcurrent() { + size := r.frame.Descriptor.Flags.BlockSizeIndex() + data = size.Get() + defer lz4block.Put(data) + } + for { + var bn int + var dst []byte + if r.isNotConcurrent() { + bn, err = r.read(data) + dst = data[:bn] + } else { + lz4block.Put(dst) + dst = <-r.reads + bn = len(dst) + if bn == 0 { + // No uncompressed data: something went wrong or we are done. + err = r.frame.Blocks.ErrorR() + } + } + switch err { + case nil: + case io.EOF: + err = r.frame.CloseR(r.src) + return + default: + return + } + r.handler(bn) + bn, err = w.Write(dst) + n += int64(bn) + if err != nil { + return + } + } +} + +// ValidFrameHeader returns a bool indicating if the given bytes slice matches a LZ4 header. +func ValidFrameHeader(in []byte) (bool, error) { + f := lz4stream.NewFrame() + err := f.ParseHeaders(bytes.NewReader(in)) + if err == nil { + return true, nil + } + if err == lz4errors.ErrInvalidFrame { + return false, nil + } + return false, err +} diff --git a/vendor/github.com/pierrec/lz4/v4/state.go b/vendor/github.com/pierrec/lz4/v4/state.go new file mode 100644 index 000000000..d94f04d05 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/state.go @@ -0,0 +1,75 @@ +package lz4 + +import ( + "errors" + "fmt" + "io" + + "github.com/pierrec/lz4/v4/internal/lz4errors" +) + +//go:generate go run golang.org/x/tools/cmd/stringer -type=aState -output state_gen.go + +const ( + noState aState = iota // uninitialized reader + errorState // unrecoverable error encountered + newState // instantiated object + readState // reading data + writeState // writing data + closedState // all done +) + +type ( + aState uint8 + _State struct { + states []aState + state aState + err error + } +) + +func (s *_State) init(states []aState) { + s.states = states + s.state = states[0] +} + +func (s *_State) reset() { + s.state = s.states[0] + s.err = nil +} + +// next sets the state to the next one unless it is passed a non nil error. +// It returns whether or not it is in error. +func (s *_State) next(err error) bool { + if err != nil { + s.err = fmt.Errorf("%s: %w", s.state, err) + s.state = errorState + return true + } + s.state = s.states[s.state] + return false +} + +// nextd is like next but for defers. +func (s *_State) nextd(errp *error) bool { + return errp != nil && s.next(*errp) +} + +// check sets s in error if not already in error and if the error is not nil or io.EOF, +func (s *_State) check(errp *error) { + if s.state == errorState || errp == nil { + return + } + if err := *errp; err != nil { + s.err = fmt.Errorf("%w[%s]", err, s.state) + if !errors.Is(err, io.EOF) { + s.state = errorState + } + } +} + +func (s *_State) fail() error { + s.state = errorState + s.err = fmt.Errorf("%w[%s]", lz4errors.ErrInternalUnhandledState, s.state) + return s.err +} diff --git a/vendor/github.com/pierrec/lz4/v4/state_gen.go b/vendor/github.com/pierrec/lz4/v4/state_gen.go new file mode 100644 index 000000000..75fb82892 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/state_gen.go @@ -0,0 +1,28 @@ +// Code generated by "stringer -type=aState -output state_gen.go"; DO NOT EDIT. + +package lz4 + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[noState-0] + _ = x[errorState-1] + _ = x[newState-2] + _ = x[readState-3] + _ = x[writeState-4] + _ = x[closedState-5] +} + +const _aState_name = "noStateerrorStatenewStatereadStatewriteStateclosedState" + +var _aState_index = [...]uint8{0, 7, 17, 25, 34, 44, 55} + +func (i aState) String() string { + if i >= aState(len(_aState_index)-1) { + return "aState(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _aState_name[_aState_index[i]:_aState_index[i+1]] +} diff --git a/vendor/github.com/pierrec/lz4/v4/writer.go b/vendor/github.com/pierrec/lz4/v4/writer.go new file mode 100644 index 000000000..4358adee1 --- /dev/null +++ b/vendor/github.com/pierrec/lz4/v4/writer.go @@ -0,0 +1,242 @@ +package lz4 + +import ( + "io" + + "github.com/pierrec/lz4/v4/internal/lz4block" + "github.com/pierrec/lz4/v4/internal/lz4errors" + "github.com/pierrec/lz4/v4/internal/lz4stream" +) + +var writerStates = []aState{ + noState: newState, + newState: writeState, + writeState: closedState, + closedState: newState, + errorState: newState, +} + +// NewWriter returns a new LZ4 frame encoder. +func NewWriter(w io.Writer) *Writer { + zw := &Writer{frame: lz4stream.NewFrame()} + zw.state.init(writerStates) + _ = zw.Apply(DefaultBlockSizeOption, DefaultChecksumOption, DefaultConcurrency, defaultOnBlockDone) + zw.Reset(w) + return zw +} + +// Writer allows writing an LZ4 stream. +type Writer struct { + state _State + src io.Writer // destination writer + level lz4block.CompressionLevel // how hard to try + num int // concurrency level + frame *lz4stream.Frame // frame being built + data []byte // pending data + idx int // size of pending data + handler func(int) + legacy bool +} + +func (*Writer) private() {} + +func (w *Writer) Apply(options ...Option) (err error) { + defer w.state.check(&err) + switch w.state.state { + case newState: + case errorState: + return w.state.err + default: + return lz4errors.ErrOptionClosedOrError + } + w.Reset(w.src) + for _, o := range options { + if err = o(w); err != nil { + return + } + } + return +} + +func (w *Writer) isNotConcurrent() bool { + return w.num == 1 +} + +// init sets up the Writer when in newState. It does not change the Writer state. +func (w *Writer) init() error { + w.frame.InitW(w.src, w.num, w.legacy) + size := w.frame.Descriptor.Flags.BlockSizeIndex() + w.data = size.Get() + w.idx = 0 + return w.frame.Descriptor.Write(w.frame, w.src) +} + +func (w *Writer) Write(buf []byte) (n int, err error) { + defer w.state.check(&err) + switch w.state.state { + case writeState: + case closedState, errorState: + return 0, w.state.err + case newState: + if err = w.init(); w.state.next(err) { + return + } + default: + return 0, w.state.fail() + } + + zn := len(w.data) + for len(buf) > 0 { + if w.isNotConcurrent() && w.idx == 0 && len(buf) >= zn { + // Avoid a copy as there is enough data for a block. + if err = w.write(buf[:zn], false); err != nil { + return + } + n += zn + buf = buf[zn:] + continue + } + // Accumulate the data to be compressed. + m := copy(w.data[w.idx:], buf) + n += m + w.idx += m + buf = buf[m:] + + if w.idx < len(w.data) { + // Buffer not filled. + return + } + + // Buffer full. + if err = w.write(w.data, true); err != nil { + return + } + if !w.isNotConcurrent() { + size := w.frame.Descriptor.Flags.BlockSizeIndex() + w.data = size.Get() + } + w.idx = 0 + } + return +} + +func (w *Writer) write(data []byte, safe bool) error { + if w.isNotConcurrent() { + block := w.frame.Blocks.Block + err := block.Compress(w.frame, data, w.level).Write(w.frame, w.src) + w.handler(len(block.Data)) + return err + } + c := make(chan *lz4stream.FrameDataBlock) + w.frame.Blocks.Blocks <- c + go func(c chan *lz4stream.FrameDataBlock, data []byte, safe bool) { + b := lz4stream.NewFrameDataBlock(w.frame) + c <- b.Compress(w.frame, data, w.level) + <-c + w.handler(len(b.Data)) + b.Close(w.frame) + if safe { + // safe to put it back as the last usage of it was FrameDataBlock.Write() called before c is closed + lz4block.Put(data) + } + }(c, data, safe) + + return nil +} + +// Flush any buffered data to the underlying writer immediately. +func (w *Writer) Flush() (err error) { + switch w.state.state { + case writeState: + case errorState: + return w.state.err + case newState: + if err = w.init(); w.state.next(err) { + return + } + default: + return nil + } + + if w.idx > 0 { + // Flush pending data, disable w.data freeing as it is done later on. + if err = w.write(w.data[:w.idx], false); err != nil { + return err + } + w.idx = 0 + } + return nil +} + +// Close closes the Writer, flushing any unwritten data to the underlying writer +// without closing it. +func (w *Writer) Close() error { + if err := w.Flush(); err != nil { + return err + } + err := w.frame.CloseW(w.src, w.num) + // It is now safe to free the buffer. + if w.data != nil { + lz4block.Put(w.data) + w.data = nil + } + return err +} + +// Reset clears the state of the Writer w such that it is equivalent to its +// initial state from NewWriter, but instead writing to writer. +// Reset keeps the previous options unless overwritten by the supplied ones. +// No access to writer is performed. +// +// w.Close must be called before Reset or pending data may be dropped. +func (w *Writer) Reset(writer io.Writer) { + w.frame.Reset(w.num) + w.state.reset() + w.src = writer +} + +// ReadFrom efficiently reads from r and compressed into the Writer destination. +func (w *Writer) ReadFrom(r io.Reader) (n int64, err error) { + switch w.state.state { + case closedState, errorState: + return 0, w.state.err + case newState: + if err = w.init(); w.state.next(err) { + return + } + default: + return 0, w.state.fail() + } + defer w.state.check(&err) + + size := w.frame.Descriptor.Flags.BlockSizeIndex() + var done bool + var rn int + data := size.Get() + if w.isNotConcurrent() { + // Keep the same buffer for the whole process. + defer lz4block.Put(data) + } + for !done { + rn, err = io.ReadFull(r, data) + switch err { + case nil: + case io.EOF, io.ErrUnexpectedEOF: // read may be partial + done = true + default: + return + } + n += int64(rn) + err = w.write(data[:rn], true) + if err != nil { + return + } + w.handler(rn) + if !done && !w.isNotConcurrent() { + // The buffer will be returned automatically by go routines (safe=true) + // so get a new one fo the next round. + data = size.Get() + } + } + return +} diff --git a/vendor/github.com/u-root/uio/LICENSE b/vendor/github.com/u-root/uio/LICENSE new file mode 100644 index 000000000..652ff7e77 --- /dev/null +++ b/vendor/github.com/u-root/uio/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2012-2021, u-root Authors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/u-root/uio/rand/random.go b/vendor/github.com/u-root/uio/rand/random.go new file mode 100644 index 000000000..e189199b9 --- /dev/null +++ b/vendor/github.com/u-root/uio/rand/random.go @@ -0,0 +1,62 @@ +// Copyright 2019 the u-root 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 rand implements cancelable reads from a cryptographically safe +// random number source. +package rand + +import ( + "context" +) + +// Reader is a cryptographically safe random number source. +var Reader = DefaultReaderWithContext(context.Background()) + +// Read blockingly reads from a random number source. +func Read(b []byte) (int, error) { + return Reader.Read(b) +} + +// ReadContext is a context-aware reader for random numbers. +func ReadContext(ctx context.Context, b []byte) (int, error) { + return Reader.ReadContext(ctx, b) +} + +// ContextReader is a cancelable io.Reader. +type ContextReader interface { + // Read behaves like a blocking io.Reader.Read. + // + // Read wraps ReadContext with a background context. + Read(b []byte) (n int, err error) + + // ReadContext is an io.Reader that blocks until data is available or + // until ctx is done. + ReadContext(ctx context.Context, b []byte) (n int, err error) +} + +// contextReader is a cancelable io.Reader. +type contextReader interface { + ReadContext(context.Context, []byte) (int, error) +} + +// ctxReader takes a contextReader and turns it into a ContextReader. +type ctxReader struct { + contextReader + ctx context.Context //nolint:containedctx +} + +func (cr ctxReader) Read(b []byte) (int, error) { + return cr.contextReader.ReadContext(cr.ctx, b) +} + +// DefaultReaderWithContext returns a context-aware io.Reader. +// +// Because this stores the context, only use this in situations where an +// io.Reader is unavoidable. +func DefaultReaderWithContext(ctx context.Context) ContextReader { + return ctxReader{ + ctx: ctx, + contextReader: defaultContextReader, + } +} diff --git a/vendor/github.com/u-root/uio/rand/random_linux.go b/vendor/github.com/u-root/uio/rand/random_linux.go new file mode 100644 index 000000000..42931cca0 --- /dev/null +++ b/vendor/github.com/u-root/uio/rand/random_linux.go @@ -0,0 +1,77 @@ +// Copyright 2019 the u-root 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 rand + +import ( + "context" + "log" + "os" + "sync" + "syscall" + "time" + + "golang.org/x/sys/unix" +) + +var defaultContextReader = &getrandomReader{} + +var backupReader = &urandomReader{} + +type getrandomReader struct { + once sync.Once + backup bool +} + +// ReadContext implements a cancelable read from /dev/urandom. +func (r *getrandomReader) ReadContext(ctx context.Context, b []byte) (int, error) { + r.once.Do(func() { + if os.Getenv("UROOT_NOHWRNG") != "" { + r.backup = true + return + } + if _, err := unix.Getrandom(b, unix.GRND_NONBLOCK); err == syscall.ENOSYS { + r.backup = true + } + }) + if r.backup { + return backupReader.ReadContext(ctx, b) + } + + for { + // getrandom(2) with GRND_NONBLOCK uses the urandom number + // source, but only returns numbers if the crng has been + // initialized. + // + // This is preferrable to /dev/urandom, as /dev/urandom will + // make up fake random numbers until the crng has been + // initialized. + n, err := unix.Getrandom(b, unix.GRND_NONBLOCK) + if err == nil { + return n, nil + } + select { + case <-ctx.Done(): + return 0, ctx.Err() + + default: + if err != syscall.EAGAIN && err != syscall.EINTR { + return n, err + } + } + } +} + +// ReadContextWithSlowLogs logs a helpful message if it takes a significant +// amount of time (>2s) to produce random data. +func (r *getrandomReader) ReadContextWithSlowLogs(ctx context.Context, b []byte) (int, error) { + d := 2 * time.Second + t := time.AfterFunc(d, func() { + log.Printf("getrandom is taking a long time (>%v). "+ + "If running on hardware, consider enabling Linux's CONFIG_RANDOM_TRUST_CPU=y. "+ + "If running in a VM/emulator, try setting up virtio-rng.", d) + }) + defer t.Stop() + return r.ReadContext(ctx, b) +} diff --git a/vendor/github.com/u-root/uio/rand/random_std.go b/vendor/github.com/u-root/uio/rand/random_std.go new file mode 100644 index 000000000..47b2e74e1 --- /dev/null +++ b/vendor/github.com/u-root/uio/rand/random_std.go @@ -0,0 +1,32 @@ +// Copyright 2020 the u-root Authors. All rights reserved +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build plan9 || windows +// +build plan9 windows + +package rand + +import ( + "context" + "crypto/rand" +) + +var defaultContextReader = &cryptoRandReader{} + +type cryptoRandReader struct{} + +// ReadContext implements a cancelable read. +func (r *cryptoRandReader) ReadContext(ctx context.Context, b []byte) (n int, err error) { + ch := make(chan struct{}) + go func() { + n, err = rand.Reader.Read(b) + close(ch) + }() + select { + case <-ctx.Done(): + return 0, ctx.Err() + case <-ch: + return n, err + } +} diff --git a/vendor/github.com/u-root/uio/rand/random_unix.go b/vendor/github.com/u-root/uio/rand/random_unix.go new file mode 100644 index 000000000..57d2e2f27 --- /dev/null +++ b/vendor/github.com/u-root/uio/rand/random_unix.go @@ -0,0 +1,10 @@ +// Copyright 2019 the u-root Authors. All rights reserved +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build aix || darwin || dragonfly || freebsd || nacl || netbsd || openbsd || solaris +// +build aix darwin dragonfly freebsd nacl netbsd openbsd solaris + +package rand + +var defaultContextReader = &urandomReader{} diff --git a/vendor/github.com/u-root/uio/rand/random_urandom.go b/vendor/github.com/u-root/uio/rand/random_urandom.go new file mode 100644 index 000000000..cd6e2639b --- /dev/null +++ b/vendor/github.com/u-root/uio/rand/random_urandom.go @@ -0,0 +1,60 @@ +// Copyright 2019 the u-root Authors. All rights reserved +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build aix || darwin || dragonfly || freebsd || nacl || netbsd || openbsd || solaris || linux +// +build aix darwin dragonfly freebsd nacl netbsd openbsd solaris linux + +package rand + +import ( + "context" + "fmt" + "sync" + "syscall" + + "golang.org/x/sys/unix" +) + +// urandomReader is a contextReader. +type urandomReader struct { + once sync.Once + + // fd is expected to be non-blocking. + fd int +} + +func (r *urandomReader) init() error { + var realErr error + r.once.Do(func() { + fd, err := unix.Open("/dev/urandom", unix.O_RDONLY, 0) + if err != nil { + realErr = fmt.Errorf("open(/dev/urandom): %v", err) + return + } + r.fd = fd + }) + return realErr +} + +// ReadContext implements a cancelable read from /dev/urandom. +func (r *urandomReader) ReadContext(ctx context.Context, b []byte) (int, error) { + if err := r.init(); err != nil { + return 0, err + } + for { + n, err := unix.Read(r.fd, b) + if err == nil { + return n, nil + } + select { + case <-ctx.Done(): + return 0, ctx.Err() + + default: + if err != syscall.EAGAIN && err != syscall.EINTR { + return n, err + } + } + } +} diff --git a/vendor/github.com/u-root/uio/uio/alignreader.go b/vendor/github.com/u-root/uio/uio/alignreader.go new file mode 100644 index 000000000..680064414 --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/alignreader.go @@ -0,0 +1,41 @@ +// Copyright 2019 the u-root 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 uio + +import ( + "io" +) + +// AlignReader keeps track of how many bytes were read so the reader can be +// aligned at a future time. +type AlignReader struct { + R io.Reader + N int +} + +// Read reads from the underlying io.Reader. +func (r *AlignReader) Read(b []byte) (int, error) { + n, err := r.R.Read(b) + r.N += n + return n, err +} + +// ReadByte reads one byte from the underlying io.Reader. +func (r *AlignReader) ReadByte() (byte, error) { + b := make([]byte, 1) + _, err := io.ReadFull(r, b) + return b[0], err +} + +// Align aligns the reader to the given number of bytes and returns the +// bytes read to pad it. +func (r *AlignReader) Align(n int) ([]byte, error) { + if r.N%n == 0 { + return []byte{}, nil + } + pad := make([]byte, n-r.N%n) + m, err := io.ReadFull(r, pad) + return pad[:m], err +} diff --git a/vendor/github.com/u-root/uio/uio/alignwriter.go b/vendor/github.com/u-root/uio/uio/alignwriter.go new file mode 100644 index 000000000..95a52f61f --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/alignwriter.go @@ -0,0 +1,34 @@ +// Copyright 2019 the u-root 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 uio + +import ( + "bytes" + "io" +) + +// AlignWriter keeps track of how many bytes were written so the writer can be +// aligned at a future time. +type AlignWriter struct { + W io.Writer + N int +} + +// Write writes to the underlying io.Writew. +func (w *AlignWriter) Write(b []byte) (int, error) { + n, err := w.W.Write(b) + w.N += n + return n, err +} + +// Align aligns the writer to the given number of bytes using the given pad +// value. +func (w *AlignWriter) Align(n int, pad byte) error { + if w.N%n == 0 { + return nil + } + _, err := w.Write(bytes.Repeat([]byte{pad}, n-w.N%n)) + return err +} diff --git a/vendor/github.com/u-root/uio/uio/archivereader.go b/vendor/github.com/u-root/uio/uio/archivereader.go new file mode 100644 index 000000000..6d0eeefcf --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/archivereader.go @@ -0,0 +1,89 @@ +// Copyright 2021 the u-root 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 uio + +import ( + "bytes" + "errors" + "io" + + "github.com/pierrec/lz4/v4" +) + +const ( + // preReadSizeBytes is the num of bytes pre-read from a io.Reader that will + // be used to match against archive header. + defaultArchivePreReadSizeBytes = 1024 +) + +// ErrPreReadError indicates there was not enough underlying data to decompress. +var ErrPreReadError = errors.New("pre-read nothing") + +// ArchiveReader reads from a io.Reader, decompresses source bytes +// when applicable. +// +// It allows probing for multiple archive format, while still able +// to read from beginning, by pre-reading a small number of bytes. +// +// Always use newArchiveReader to initialize. +type ArchiveReader struct { + // src is where we read source bytes. + src io.Reader + + // buf stores pre-read bytes from original io.Reader. Archive format + // detection will be done against it. + buf []byte + + // preReadSizeBytes is how many bytes we pre-read for magic number + // matching for each archive type. This should be greater than or + // equal to the largest header frame size of each supported archive + // format. + preReadSizeBytes int +} + +// NewArchiveReader is a decompression reader. +func NewArchiveReader(r io.Reader) (ArchiveReader, error) { + ar := ArchiveReader{ + src: r, + // Randomly chosen, should be enough for most types: + // + // e.g. gzip with 10 byte header, lz4 with a header size + // between 7 and 19 bytes. + preReadSizeBytes: defaultArchivePreReadSizeBytes, + } + pbuf := make([]byte, ar.preReadSizeBytes) + + nr, err := io.ReadFull(r, pbuf) + // In case the image is smaller pre-read block size, 1kb for now. + // Ever possible ? probably not in case a compression is needed! + ar.buf = pbuf[:nr] + if err == io.EOF { + // If we could not pre-read anything, we can't determine if + // it is a compressed file. + ar.src = io.MultiReader(bytes.NewReader(pbuf[:nr]), r) + return ar, ErrPreReadError + } + + // Try each supported compression type, return upon first match. + + // Try lz4. + // magic number error will be thrown if source is not a lz4 archive. + // e.g. "lz4: bad magic number". + if ok, err := lz4.ValidFrameHeader(ar.buf); err == nil && ok { + ar.src = lz4.NewReader(io.MultiReader(bytes.NewReader(ar.buf), r)) + return ar, nil + } + + // Try other archive types here, gzip, xz, etc when needed. + + // Last resort, read as is. + ar.src = io.MultiReader(bytes.NewReader(ar.buf), r) + return ar, nil +} + +// Read reads from the archive uncompressed. +func (ar ArchiveReader) Read(p []byte) (n int, err error) { + return ar.src.Read(p) +} diff --git a/vendor/github.com/u-root/uio/uio/buffer.go b/vendor/github.com/u-root/uio/uio/buffer.go new file mode 100644 index 000000000..a0a603bb9 --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/buffer.go @@ -0,0 +1,380 @@ +// Copyright 2018 the u-root 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 uio + +import ( + "encoding/binary" + "errors" + "fmt" +) + +// Marshaler is the interface implemented by an object that can marshal itself +// into binary form. +// +// Marshal appends data to the buffer b. +type Marshaler interface { + Marshal(l *Lexer) +} + +// Unmarshaler is the interface implemented by an object that can unmarshal a +// binary representation of itself. +// +// Unmarshal Consumes data from the buffer b. +type Unmarshaler interface { + Unmarshal(l *Lexer) error +} + +// ToBytes marshals m in the given byte order. +func ToBytes(m Marshaler, order binary.ByteOrder) []byte { + l := NewLexer(NewBuffer(nil), order) + m.Marshal(l) + return l.Data() +} + +// FromBytes unmarshals b into obj in the given byte order. +func FromBytes(obj Unmarshaler, b []byte, order binary.ByteOrder) error { + l := NewLexer(NewBuffer(b), order) + return obj.Unmarshal(l) +} + +// ToBigEndian marshals m to big endian byte order. +func ToBigEndian(m Marshaler) []byte { + l := NewBigEndianBuffer(nil) + m.Marshal(l) + return l.Data() +} + +// FromBigEndian unmarshals b into obj in big endian byte order. +func FromBigEndian(obj Unmarshaler, b []byte) error { + l := NewBigEndianBuffer(b) + return obj.Unmarshal(l) +} + +// ToLittleEndian marshals m to little endian byte order. +func ToLittleEndian(m Marshaler) []byte { + l := NewLittleEndianBuffer(nil) + m.Marshal(l) + return l.Data() +} + +// FromLittleEndian unmarshals b into obj in little endian byte order. +func FromLittleEndian(obj Unmarshaler, b []byte) error { + l := NewLittleEndianBuffer(b) + return obj.Unmarshal(l) +} + +// Buffer implements functions to manipulate byte slices in a zero-copy way. +type Buffer struct { + // data is the underlying data. + data []byte + + // byteCount keeps track of how many bytes have been consumed for + // debugging. + byteCount int +} + +// NewBuffer Consumes b for marshaling or unmarshaling in the given byte order. +func NewBuffer(b []byte) *Buffer { + return &Buffer{data: b} +} + +// Preallocate increases the capacity of the buffer by n bytes. +func (b *Buffer) Preallocate(n int) { + b.data = append(b.data, make([]byte, 0, n)...) +} + +// WriteN appends n bytes to the Buffer and returns a slice pointing to the +// newly appended bytes. +func (b *Buffer) WriteN(n int) []byte { + b.data = append(b.data, make([]byte, n)...) + return b.data[len(b.data)-n:] +} + +// ErrBufferTooShort is returned when a caller wants to read more bytes than +// are available in the buffer. +var ErrBufferTooShort = errors.New("buffer too short") + +// ReadN consumes n bytes from the Buffer. It returns nil, false if there +// aren't enough bytes left. +func (b *Buffer) ReadN(n int) ([]byte, error) { + if !b.Has(n) { + return nil, fmt.Errorf("%w at position %d: have %d bytes, want %d bytes", ErrBufferTooShort, b.byteCount, b.Len(), n) + } + rval := b.data[:n] + b.data = b.data[n:] + b.byteCount += n + return rval, nil +} + +// Data is unConsumed data remaining in the Buffer. +func (b *Buffer) Data() []byte { + return b.data +} + +// Has returns true if n bytes are available. +func (b *Buffer) Has(n int) bool { + return len(b.data) >= n +} + +// Len returns the length of the remaining bytes. +func (b *Buffer) Len() int { + return len(b.data) +} + +// Cap returns the available capacity. +func (b *Buffer) Cap() int { + return cap(b.data) +} + +// Lexer is a convenient encoder/decoder for buffers. +// +// Use: +// +// func (s *something) Unmarshal(l *Lexer) { +// s.Foo = l.Read8() +// s.Bar = l.Read8() +// s.Baz = l.Read16() +// return l.Error() +// } +type Lexer struct { + *Buffer + + // order is the byte order to write in / read in. + order binary.ByteOrder + + // err + err error +} + +// NewLexer returns a new coder for buffers. +func NewLexer(b *Buffer, order binary.ByteOrder) *Lexer { + return &Lexer{ + Buffer: b, + order: order, + } +} + +// NewLittleEndianBuffer returns a new little endian coder for a new buffer. +func NewLittleEndianBuffer(b []byte) *Lexer { + return &Lexer{ + Buffer: NewBuffer(b), + order: binary.LittleEndian, + } +} + +// NewBigEndianBuffer returns a new big endian coder for a new buffer. +func NewBigEndianBuffer(b []byte) *Lexer { + return &Lexer{ + Buffer: NewBuffer(b), + order: binary.BigEndian, + } +} + +// NewNativeEndianBuffer returns a new native endian coder for a new buffer. +func NewNativeEndianBuffer(b []byte) *Lexer { + return &Lexer{ + Buffer: NewBuffer(b), + order: binary.NativeEndian, + } +} + +// SetError sets the error if no error has previously been set. +// +// The error can later be retried with Error or FinError methods. +func (l *Lexer) SetError(err error) { + if l.err == nil { + l.err = err + } +} + +// Consume returns a slice of the next n bytes from the buffer. +// +// Consume gives direct access to the underlying data. +func (l *Lexer) Consume(n int) []byte { + v, err := l.Buffer.ReadN(n) + if err != nil { + l.SetError(err) + return nil + } + return v +} + +func (l *Lexer) append(n int) []byte { + return l.Buffer.WriteN(n) +} + +// Error returns an error if an error occurred reading from the buffer. +func (l *Lexer) Error() error { + return l.err +} + +// ErrUnreadBytes is returned when there is more data left to read in the buffer. +var ErrUnreadBytes = errors.New("buffer contains unread bytes") + +// FinError returns an error if an error occurred or if there is more data left +// to read in the buffer. +func (l *Lexer) FinError() error { + if l.err != nil { + return l.err + } + if l.Buffer.Len() > 0 { + return ErrUnreadBytes + } + return nil +} + +// Read8 reads a byte from the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Read8() uint8 { + v := l.Consume(1) + if v == nil { + return 0 + } + return v[0] +} + +// Read16 reads a 16-bit value from the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Read16() uint16 { + v := l.Consume(2) + if v == nil { + return 0 + } + return l.order.Uint16(v) +} + +// Read32 reads a 32-bit value from the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Read32() uint32 { + v := l.Consume(4) + if v == nil { + return 0 + } + return l.order.Uint32(v) +} + +// Read64 reads a 64-bit value from the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Read64() uint64 { + v := l.Consume(8) + if v == nil { + return 0 + } + return l.order.Uint64(v) +} + +// CopyN returns a copy of the next n bytes. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) CopyN(n int) []byte { + v := l.Consume(n) + if v == nil { + return nil + } + + p := make([]byte, n) + m := copy(p, v) + return p[:m] +} + +// ReadAll Consumes and returns a copy of all remaining bytes in the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) ReadAll() []byte { + return l.CopyN(l.Len()) +} + +// ReadBytes reads exactly len(p) values from the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) ReadBytes(p []byte) { + copy(p, l.Consume(len(p))) +} + +// Read implements io.Reader.Read. +func (l *Lexer) Read(p []byte) (int, error) { + v := l.Consume(len(p)) + if v == nil { + return 0, l.Error() + } + return copy(p, v), nil +} + +// ReadData reads the binary representation of data from the buffer. +// +// See binary.Read. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) ReadData(data interface{}) { + l.SetError(binary.Read(l, l.order, data)) +} + +// WriteData writes a binary representation of data to the buffer. +// +// See binary.Write. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) WriteData(data interface{}) { + l.SetError(binary.Write(l, l.order, data)) +} + +// Write8 writes a byte to the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Write8(v uint8) { + l.append(1)[0] = v +} + +// Write16 writes a 16-bit value to the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Write16(v uint16) { + l.order.PutUint16(l.append(2), v) +} + +// Write32 writes a 32-bit value to the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Write32(v uint32) { + l.order.PutUint32(l.append(4), v) +} + +// Write64 writes a 64-bit value to the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Write64(v uint64) { + l.order.PutUint64(l.append(8), v) +} + +// Append returns a newly appended n-size Buffer to write to. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Append(n int) []byte { + return l.append(n) +} + +// WriteBytes writes p to the Buffer. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) WriteBytes(p []byte) { + copy(l.append(len(p)), p) +} + +// Write implements io.Writer.Write. +// +// If an error occurred, Error() will return a non-nil error. +func (l *Lexer) Write(p []byte) (int, error) { + return copy(l.append(len(p)), p), nil +} + +// Align appends bytes to align the length of the buffer to be divisible by n. +func (l *Lexer) Align(n int) { + pad := ((l.Len() + n - 1) &^ (n - 1)) - l.Len() + l.Append(pad) +} diff --git a/vendor/github.com/u-root/uio/uio/cached.go b/vendor/github.com/u-root/uio/uio/cached.go new file mode 100644 index 000000000..a39ff981e --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/cached.go @@ -0,0 +1,98 @@ +// Copyright 2018 the u-root 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 uio + +import ( + "bytes" + "io" +) + +// CachingReader is a lazily caching wrapper of an io.Reader. +// +// The wrapped io.Reader is only read from on demand, not upfront. +type CachingReader struct { + buf bytes.Buffer + r io.Reader + pos int + eof bool +} + +// NewCachingReader buffers reads from r. +// +// r is only read from when Read() is called. +func NewCachingReader(r io.Reader) *CachingReader { + return &CachingReader{ + r: r, + } +} + +func (cr *CachingReader) read(p []byte) (int, error) { + n, err := cr.r.Read(p) + cr.buf.Write(p[:n]) + if err == io.EOF || (n == 0 && err == nil) { + cr.eof = true + return n, io.EOF + } + return n, err +} + +// NewReader returns a new io.Reader that reads cr from offset 0. +func (cr *CachingReader) NewReader() io.Reader { + return Reader(cr) +} + +// Read reads from cr; implementing io.Reader. +// +// TODO(chrisko): Decide whether to keep this or only keep NewReader(). +func (cr *CachingReader) Read(p []byte) (int, error) { + n, err := cr.ReadAt(p, int64(cr.pos)) + cr.pos += n + return n, err +} + +// ReadAt reads from cr; implementing io.ReaderAt. +func (cr *CachingReader) ReadAt(p []byte, off int64) (int, error) { + if len(p) == 0 { + return 0, nil + } + end := int(off) + len(p) + + // Is the caller asking for some uncached bytes? + unread := end - cr.buf.Len() + if unread > 0 { + // Avoiding allocations: use `p` to read more bytes. + for unread > 0 { + toRead := unread % len(p) + if toRead == 0 { + toRead = len(p) + } + + m, err := cr.read(p[:toRead]) + unread -= m + if err == io.EOF { + break + } + if err != nil { + return 0, err + } + } + } + + // If this is true, the entire file was read just to find out, but the + // offset is beyond the end of the file. + if off > int64(cr.buf.Len()) { + return 0, io.EOF + } + + var err error + // Did the caller ask for more than was available? + // + // Note that any io.ReaderAt implementation *must* return an error for + // short reads. + if cr.eof && unread > 0 { + err = io.EOF + } + return copy(p, cr.buf.Bytes()[off:]), err +} diff --git a/vendor/github.com/u-root/uio/uio/lazy.go b/vendor/github.com/u-root/uio/uio/lazy.go new file mode 100644 index 000000000..4cb06ac32 --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/lazy.go @@ -0,0 +1,165 @@ +// Copyright 2018 the u-root 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 uio + +import ( + "fmt" + "io" + "os" +) + +// ReadOneByte reads one byte from given io.ReaderAt. +func ReadOneByte(r io.ReaderAt) error { + buf := make([]byte, 1) + n, err := r.ReadAt(buf, 0) + if err != nil { + return err + } + if n != 1 { + return fmt.Errorf("expected to read 1 byte, but got %d", n) + } + return nil +} + +// LazyOpener is a lazy io.Reader. +// +// LazyOpener will use a given open function to derive an io.Reader when Read +// is first called on the LazyOpener. +type LazyOpener struct { + r io.Reader + s string + err error + open func() (io.Reader, error) +} + +// NewLazyOpener returns a lazy io.Reader based on `open`. +func NewLazyOpener(filename string, open func() (io.Reader, error)) *LazyOpener { + if len(filename) == 0 { + return nil + } + return &LazyOpener{s: filename, open: open} +} + +// Read implements io.Reader.Read lazily. +// +// If called for the first time, the underlying reader will be obtained and +// then used for the first and subsequent calls to Read. +func (lr *LazyOpener) Read(p []byte) (int, error) { + if lr.r == nil && lr.err == nil { + lr.r, lr.err = lr.open() + } + if lr.err != nil { + return 0, lr.err + } + return lr.r.Read(p) +} + +// String implements fmt.Stringer. +func (lr *LazyOpener) String() string { + if len(lr.s) > 0 { + return lr.s + } + if lr.r != nil { + return fmt.Sprintf("%v", lr.r) + } + return "unopened mystery file" +} + +// Close implements io.Closer.Close. +func (lr *LazyOpener) Close() error { + if c, ok := lr.r.(io.Closer); ok { + return c.Close() + } + return nil +} + +// LazyOpenerAt is a lazy io.ReaderAt. +// +// LazyOpenerAt will use a given open function to derive an io.ReaderAt when +// ReadAt is first called. +type LazyOpenerAt struct { + r io.ReaderAt + s string + err error + limit int64 + open func() (io.ReaderAt, error) +} + +// NewLazyFile returns a lazy ReaderAt opened from path. +func NewLazyFile(path string) *LazyOpenerAt { + if len(path) == 0 { + return nil + } + return NewLazyOpenerAt(path, func() (io.ReaderAt, error) { + return os.Open(path) + }) +} + +// NewLazyLimitFile returns a lazy ReaderAt opened from path with a limit reader on it. +func NewLazyLimitFile(path string, limit int64) *LazyOpenerAt { + if len(path) == 0 { + return nil + } + return NewLazyLimitOpenerAt(path, limit, func() (io.ReaderAt, error) { + return os.Open(path) + }) +} + +// NewLazyOpenerAt returns a lazy io.ReaderAt based on `open`. +func NewLazyOpenerAt(filename string, open func() (io.ReaderAt, error)) *LazyOpenerAt { + return &LazyOpenerAt{s: filename, open: open, limit: -1} +} + +// NewLazyLimitOpenerAt returns a lazy io.ReaderAt based on `open`. +func NewLazyLimitOpenerAt(filename string, limit int64, open func() (io.ReaderAt, error)) *LazyOpenerAt { + return &LazyOpenerAt{s: filename, open: open, limit: limit} +} + +// String implements fmt.Stringer. +func (loa *LazyOpenerAt) String() string { + if len(loa.s) > 0 { + return loa.s + } + if loa.r != nil { + return fmt.Sprintf("%v", loa.r) + } + return "unopened mystery file" +} + +// File returns the backend file of the io.ReaderAt if it +// is backed by a os.File. +func (loa *LazyOpenerAt) File() *os.File { + if f, ok := loa.r.(*os.File); ok { + return f + } + return nil +} + +// ReadAt implements io.ReaderAt.ReadAt. +func (loa *LazyOpenerAt) ReadAt(p []byte, off int64) (int, error) { + if loa.r == nil && loa.err == nil { + loa.r, loa.err = loa.open() + } + if loa.err != nil { + return 0, loa.err + } + if loa.limit > 0 { + if off >= loa.limit { + return 0, io.EOF + } + if int64(len(p)) > loa.limit-off { + p = p[0 : loa.limit-off] + } + } + return loa.r.ReadAt(p, off) +} + +// Close implements io.Closer.Close. +func (loa *LazyOpenerAt) Close() error { + if c, ok := loa.r.(io.Closer); ok { + return c.Close() + } + return nil +} diff --git a/vendor/github.com/u-root/uio/uio/null.go b/vendor/github.com/u-root/uio/uio/null.go new file mode 100644 index 000000000..1c89f7410 --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/null.go @@ -0,0 +1,76 @@ +// Copyright 2012-2019 the u-root Authors. All rights reserved +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Discard implementation copied from the Go project: +// https://golang.org/src/io/ioutil/ioutil.go. +// Copyright 2009 The Go Authors. All rights reserved. + +package uio + +import ( + "io" + "sync" +) + +// devNull implements an io.Writer and io.ReaderFrom that discards any writes. +type devNull struct{} + +// devNull implements ReaderFrom as an optimization so io.Copy to +// ioutil.Discard can avoid doing unnecessary work. +var _ io.ReaderFrom = devNull{} + +// Write is an io.Writer.Write that discards data. +func (devNull) Write(p []byte) (int, error) { + return len(p), nil +} + +// Name is like os.File.Name() and returns "null". +func (devNull) Name() string { + return "null" +} + +// WriteString implements io.StringWriter and discards given data. +func (devNull) WriteString(s string) (int, error) { + return len(s), nil +} + +var blackHolePool = sync.Pool{ + New: func() interface{} { + b := make([]byte, 8192) + return &b + }, +} + +// ReadFrom implements io.ReaderFrom and discards data being read. +func (devNull) ReadFrom(r io.Reader) (n int64, err error) { + bufp := blackHolePool.Get().(*[]byte) + var readSize int + for { + readSize, err = r.Read(*bufp) + n += int64(readSize) + if err != nil { + blackHolePool.Put(bufp) + if err == io.EOF { + return n, nil + } + return + } + } +} + +// Close does nothing. +func (devNull) Close() error { + return nil +} + +// WriteNameCloser is the interface that groups Write, Close, and Name methods. +type WriteNameCloser interface { + io.Writer + io.Closer + Name() string +} + +// Discard is a WriteNameCloser on which all Write and Close calls succeed +// without doing anything, and the Name call returns "null". +var Discard WriteNameCloser = devNull{} diff --git a/vendor/github.com/u-root/uio/uio/progress.go b/vendor/github.com/u-root/uio/uio/progress.go new file mode 100644 index 000000000..3aa2a3e06 --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/progress.go @@ -0,0 +1,42 @@ +// Copyright 2019 the u-root 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 uio + +import ( + "io" + "strings" +) + +// ProgressReadCloser implements io.ReadCloser and prints Symbol to W after every +// Interval bytes passes through RC. +type ProgressReadCloser struct { + RC io.ReadCloser + + Symbol string + Interval int + W io.Writer + + counter int + written bool +} + +// Read implements io.Reader for ProgressReadCloser. +func (rc *ProgressReadCloser) Read(p []byte) (n int, err error) { + defer func() { + numSymbols := (rc.counter%rc.Interval + n) / rc.Interval + _, _ = rc.W.Write([]byte(strings.Repeat(rc.Symbol, numSymbols))) + rc.counter += n + rc.written = (rc.written || numSymbols > 0) + if err == io.EOF && rc.written { + _, _ = rc.W.Write([]byte("\n")) + } + }() + return rc.RC.Read(p) +} + +// Close implements io.Closer for ProgressReader. +func (rc *ProgressReadCloser) Close() error { + return rc.RC.Close() +} diff --git a/vendor/github.com/u-root/uio/uio/reader.go b/vendor/github.com/u-root/uio/uio/reader.go new file mode 100644 index 000000000..0ca839a07 --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/reader.go @@ -0,0 +1,67 @@ +// Copyright 2018 the u-root 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 uio + +import ( + "bytes" + "io" + "math" + "os" + "reflect" +) + +type inMemReaderAt interface { + Bytes() []byte +} + +// ReadAll reads everything that r contains. +// +// Callers *must* not modify bytes in the returned byte slice. +// +// If r is an in-memory representation, ReadAll will attempt to return a +// pointer to those bytes directly. +func ReadAll(r io.ReaderAt) ([]byte, error) { + if imra, ok := r.(inMemReaderAt); ok { + return imra.Bytes(), nil + } + return io.ReadAll(Reader(r)) +} + +// Reader generates a Reader from a ReaderAt. +func Reader(r io.ReaderAt) io.Reader { + return io.NewSectionReader(r, 0, math.MaxInt64) +} + +// ReaderAtEqual compares the contents of r1 and r2. +func ReaderAtEqual(r1, r2 io.ReaderAt) bool { + var c, d []byte + var r1err, r2err error + if r1 != nil { + c, r1err = ReadAll(r1) + } + if r2 != nil { + d, r2err = ReadAll(r2) + } + return bytes.Equal(c, d) && reflect.DeepEqual(r1err, r2err) +} + +// ReadIntoFile reads all from io.Reader into the file at given path. +// +// If the file at given path does not exist, a new file will be created. +// If the file exists at the given path, but not empty, it will be truncated. +func ReadIntoFile(r io.Reader, p string) error { + f, err := os.OpenFile(p, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o644) + if err != nil { + return err + } + defer f.Close() + + _, err = io.Copy(f, r) + if err != nil { + return err + } + + return f.Close() +} diff --git a/vendor/github.com/u-root/uio/uio/uio.go b/vendor/github.com/u-root/uio/uio/uio.go new file mode 100644 index 000000000..bdd507c8e --- /dev/null +++ b/vendor/github.com/u-root/uio/uio/uio.go @@ -0,0 +1,9 @@ +// Copyright 2018 the u-root 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 uio unifies commonly used io utilities for u-root. +// +// uio's most used feature is the Buffer/Lexer combination to parse binary data +// of arbitrary endianness into data structures. +package uio diff --git a/vendor/golang.org/x/net/internal/iana/const.go b/vendor/golang.org/x/net/internal/iana/const.go deleted file mode 100644 index cea712fac..000000000 --- a/vendor/golang.org/x/net/internal/iana/const.go +++ /dev/null @@ -1,223 +0,0 @@ -// go generate gen.go -// Code generated by the command above; DO NOT EDIT. - -// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA). -package iana // import "golang.org/x/net/internal/iana" - -// Differentiated Services Field Codepoints (DSCP), Updated: 2018-05-04 -const ( - DiffServCS0 = 0x00 // CS0 - DiffServCS1 = 0x20 // CS1 - DiffServCS2 = 0x40 // CS2 - DiffServCS3 = 0x60 // CS3 - DiffServCS4 = 0x80 // CS4 - DiffServCS5 = 0xa0 // CS5 - DiffServCS6 = 0xc0 // CS6 - DiffServCS7 = 0xe0 // CS7 - DiffServAF11 = 0x28 // AF11 - DiffServAF12 = 0x30 // AF12 - DiffServAF13 = 0x38 // AF13 - DiffServAF21 = 0x48 // AF21 - DiffServAF22 = 0x50 // AF22 - DiffServAF23 = 0x58 // AF23 - DiffServAF31 = 0x68 // AF31 - DiffServAF32 = 0x70 // AF32 - DiffServAF33 = 0x78 // AF33 - DiffServAF41 = 0x88 // AF41 - DiffServAF42 = 0x90 // AF42 - DiffServAF43 = 0x98 // AF43 - DiffServEF = 0xb8 // EF - DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT - NotECNTransport = 0x00 // Not-ECT (Not ECN-Capable Transport) - ECNTransport1 = 0x01 // ECT(1) (ECN-Capable Transport(1)) - ECNTransport0 = 0x02 // ECT(0) (ECN-Capable Transport(0)) - CongestionExperienced = 0x03 // CE (Congestion Experienced) -) - -// Protocol Numbers, Updated: 2017-10-13 -const ( - ProtocolIP = 0 // IPv4 encapsulation, pseudo protocol number - ProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option - ProtocolICMP = 1 // Internet Control Message - ProtocolIGMP = 2 // Internet Group Management - ProtocolGGP = 3 // Gateway-to-Gateway - ProtocolIPv4 = 4 // IPv4 encapsulation - ProtocolST = 5 // Stream - ProtocolTCP = 6 // Transmission Control - ProtocolCBT = 7 // CBT - ProtocolEGP = 8 // Exterior Gateway Protocol - ProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP) - ProtocolBBNRCCMON = 10 // BBN RCC Monitoring - ProtocolNVPII = 11 // Network Voice Protocol - ProtocolPUP = 12 // PUP - ProtocolEMCON = 14 // EMCON - ProtocolXNET = 15 // Cross Net Debugger - ProtocolCHAOS = 16 // Chaos - ProtocolUDP = 17 // User Datagram - ProtocolMUX = 18 // Multiplexing - ProtocolDCNMEAS = 19 // DCN Measurement Subsystems - ProtocolHMP = 20 // Host Monitoring - ProtocolPRM = 21 // Packet Radio Measurement - ProtocolXNSIDP = 22 // XEROX NS IDP - ProtocolTRUNK1 = 23 // Trunk-1 - ProtocolTRUNK2 = 24 // Trunk-2 - ProtocolLEAF1 = 25 // Leaf-1 - ProtocolLEAF2 = 26 // Leaf-2 - ProtocolRDP = 27 // Reliable Data Protocol - ProtocolIRTP = 28 // Internet Reliable Transaction - ProtocolISOTP4 = 29 // ISO Transport Protocol Class 4 - ProtocolNETBLT = 30 // Bulk Data Transfer Protocol - ProtocolMFENSP = 31 // MFE Network Services Protocol - ProtocolMERITINP = 32 // MERIT Internodal Protocol - ProtocolDCCP = 33 // Datagram Congestion Control Protocol - Protocol3PC = 34 // Third Party Connect Protocol - ProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol - ProtocolXTP = 36 // XTP - ProtocolDDP = 37 // Datagram Delivery Protocol - ProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto - ProtocolTPPP = 39 // TP++ Transport Protocol - ProtocolIL = 40 // IL Transport Protocol - ProtocolIPv6 = 41 // IPv6 encapsulation - ProtocolSDRP = 42 // Source Demand Routing Protocol - ProtocolIPv6Route = 43 // Routing Header for IPv6 - ProtocolIPv6Frag = 44 // Fragment Header for IPv6 - ProtocolIDRP = 45 // Inter-Domain Routing Protocol - ProtocolRSVP = 46 // Reservation Protocol - ProtocolGRE = 47 // Generic Routing Encapsulation - ProtocolDSR = 48 // Dynamic Source Routing Protocol - ProtocolBNA = 49 // BNA - ProtocolESP = 50 // Encap Security Payload - ProtocolAH = 51 // Authentication Header - ProtocolINLSP = 52 // Integrated Net Layer Security TUBA - ProtocolNARP = 54 // NBMA Address Resolution Protocol - ProtocolMOBILE = 55 // IP Mobility - ProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management - ProtocolSKIP = 57 // SKIP - ProtocolIPv6ICMP = 58 // ICMP for IPv6 - ProtocolIPv6NoNxt = 59 // No Next Header for IPv6 - ProtocolIPv6Opts = 60 // Destination Options for IPv6 - ProtocolCFTP = 62 // CFTP - ProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK - ProtocolKRYPTOLAN = 65 // Kryptolan - ProtocolRVD = 66 // MIT Remote Virtual Disk Protocol - ProtocolIPPC = 67 // Internet Pluribus Packet Core - ProtocolSATMON = 69 // SATNET Monitoring - ProtocolVISA = 70 // VISA Protocol - ProtocolIPCV = 71 // Internet Packet Core Utility - ProtocolCPNX = 72 // Computer Protocol Network Executive - ProtocolCPHB = 73 // Computer Protocol Heart Beat - ProtocolWSN = 74 // Wang Span Network - ProtocolPVP = 75 // Packet Video Protocol - ProtocolBRSATMON = 76 // Backroom SATNET Monitoring - ProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary - ProtocolWBMON = 78 // WIDEBAND Monitoring - ProtocolWBEXPAK = 79 // WIDEBAND EXPAK - ProtocolISOIP = 80 // ISO Internet Protocol - ProtocolVMTP = 81 // VMTP - ProtocolSECUREVMTP = 82 // SECURE-VMTP - ProtocolVINES = 83 // VINES - ProtocolTTP = 84 // Transaction Transport Protocol - ProtocolIPTM = 84 // Internet Protocol Traffic Manager - ProtocolNSFNETIGP = 85 // NSFNET-IGP - ProtocolDGP = 86 // Dissimilar Gateway Protocol - ProtocolTCF = 87 // TCF - ProtocolEIGRP = 88 // EIGRP - ProtocolOSPFIGP = 89 // OSPFIGP - ProtocolSpriteRPC = 90 // Sprite RPC Protocol - ProtocolLARP = 91 // Locus Address Resolution Protocol - ProtocolMTP = 92 // Multicast Transport Protocol - ProtocolAX25 = 93 // AX.25 Frames - ProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol - ProtocolSCCSP = 96 // Semaphore Communications Sec. Pro. - ProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation - ProtocolENCAP = 98 // Encapsulation Header - ProtocolGMTP = 100 // GMTP - ProtocolIFMP = 101 // Ipsilon Flow Management Protocol - ProtocolPNNI = 102 // PNNI over IP - ProtocolPIM = 103 // Protocol Independent Multicast - ProtocolARIS = 104 // ARIS - ProtocolSCPS = 105 // SCPS - ProtocolQNX = 106 // QNX - ProtocolAN = 107 // Active Networks - ProtocolIPComp = 108 // IP Payload Compression Protocol - ProtocolSNP = 109 // Sitara Networks Protocol - ProtocolCompaqPeer = 110 // Compaq Peer Protocol - ProtocolIPXinIP = 111 // IPX in IP - ProtocolVRRP = 112 // Virtual Router Redundancy Protocol - ProtocolPGM = 113 // PGM Reliable Transport Protocol - ProtocolL2TP = 115 // Layer Two Tunneling Protocol - ProtocolDDX = 116 // D-II Data Exchange (DDX) - ProtocolIATP = 117 // Interactive Agent Transfer Protocol - ProtocolSTP = 118 // Schedule Transfer Protocol - ProtocolSRP = 119 // SpectraLink Radio Protocol - ProtocolUTI = 120 // UTI - ProtocolSMP = 121 // Simple Message Protocol - ProtocolPTP = 123 // Performance Transparency Protocol - ProtocolISIS = 124 // ISIS over IPv4 - ProtocolFIRE = 125 // FIRE - ProtocolCRTP = 126 // Combat Radio Transport Protocol - ProtocolCRUDP = 127 // Combat Radio User Datagram - ProtocolSSCOPMCE = 128 // SSCOPMCE - ProtocolIPLT = 129 // IPLT - ProtocolSPS = 130 // Secure Packet Shield - ProtocolPIPE = 131 // Private IP Encapsulation within IP - ProtocolSCTP = 132 // Stream Control Transmission Protocol - ProtocolFC = 133 // Fibre Channel - ProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE - ProtocolMobilityHeader = 135 // Mobility Header - ProtocolUDPLite = 136 // UDPLite - ProtocolMPLSinIP = 137 // MPLS-in-IP - ProtocolMANET = 138 // MANET Protocols - ProtocolHIP = 139 // Host Identity Protocol - ProtocolShim6 = 140 // Shim6 Protocol - ProtocolWESP = 141 // Wrapped Encapsulating Security Payload - ProtocolROHC = 142 // Robust Header Compression - ProtocolReserved = 255 // Reserved -) - -// Address Family Numbers, Updated: 2018-04-02 -const ( - AddrFamilyIPv4 = 1 // IP (IP version 4) - AddrFamilyIPv6 = 2 // IP6 (IP version 6) - AddrFamilyNSAP = 3 // NSAP - AddrFamilyHDLC = 4 // HDLC (8-bit multidrop) - AddrFamilyBBN1822 = 5 // BBN 1822 - AddrFamily802 = 6 // 802 (includes all 802 media plus Ethernet "canonical format") - AddrFamilyE163 = 7 // E.163 - AddrFamilyE164 = 8 // E.164 (SMDS, Frame Relay, ATM) - AddrFamilyF69 = 9 // F.69 (Telex) - AddrFamilyX121 = 10 // X.121 (X.25, Frame Relay) - AddrFamilyIPX = 11 // IPX - AddrFamilyAppletalk = 12 // Appletalk - AddrFamilyDecnetIV = 13 // Decnet IV - AddrFamilyBanyanVines = 14 // Banyan Vines - AddrFamilyE164withSubaddress = 15 // E.164 with NSAP format subaddress - AddrFamilyDNS = 16 // DNS (Domain Name System) - AddrFamilyDistinguishedName = 17 // Distinguished Name - AddrFamilyASNumber = 18 // AS Number - AddrFamilyXTPoverIPv4 = 19 // XTP over IP version 4 - AddrFamilyXTPoverIPv6 = 20 // XTP over IP version 6 - AddrFamilyXTPnativemodeXTP = 21 // XTP native mode XTP - AddrFamilyFibreChannelWorldWidePortName = 22 // Fibre Channel World-Wide Port Name - AddrFamilyFibreChannelWorldWideNodeName = 23 // Fibre Channel World-Wide Node Name - AddrFamilyGWID = 24 // GWID - AddrFamilyL2VPN = 25 // AFI for L2VPN information - AddrFamilyMPLSTPSectionEndpointID = 26 // MPLS-TP Section Endpoint Identifier - AddrFamilyMPLSTPLSPEndpointID = 27 // MPLS-TP LSP Endpoint Identifier - AddrFamilyMPLSTPPseudowireEndpointID = 28 // MPLS-TP Pseudowire Endpoint Identifier - AddrFamilyMTIPv4 = 29 // MT IP: Multi-Topology IP version 4 - AddrFamilyMTIPv6 = 30 // MT IPv6: Multi-Topology IP version 6 - AddrFamilyEIGRPCommonServiceFamily = 16384 // EIGRP Common Service Family - AddrFamilyEIGRPIPv4ServiceFamily = 16385 // EIGRP IPv4 Service Family - AddrFamilyEIGRPIPv6ServiceFamily = 16386 // EIGRP IPv6 Service Family - AddrFamilyLISPCanonicalAddressFormat = 16387 // LISP Canonical Address Format (LCAF) - AddrFamilyBGPLS = 16388 // BGP-LS - AddrFamily48bitMAC = 16389 // 48-bit MAC - AddrFamily64bitMAC = 16390 // 64-bit MAC - AddrFamilyOUI = 16391 // OUI - AddrFamilyMACFinal24bits = 16392 // MAC/24 - AddrFamilyMACFinal40bits = 16393 // MAC/40 - AddrFamilyIPv6Initial64bits = 16394 // IPv6/64 - AddrFamilyRBridgePortID = 16395 // RBridge Port ID - AddrFamilyTRILLNickname = 16396 // TRILL Nickname -) diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr.go b/vendor/golang.org/x/net/internal/socket/cmsghdr.go deleted file mode 100644 index 33a5bf59c..000000000 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos - -package socket - -func (h *cmsghdr) len() int { return int(h.Len) } -func (h *cmsghdr) lvl() int { return int(h.Level) } -func (h *cmsghdr) typ() int { return int(h.Type) } diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go deleted file mode 100644 index 68f438c84..000000000 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd - -package socket - -func (h *cmsghdr) set(l, lvl, typ int) { - h.Len = uint32(l) - h.Level = int32(lvl) - h.Type = int32(typ) -} diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go deleted file mode 100644 index 058ea8de8..000000000 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_32bit.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (arm || mips || mipsle || 386 || ppc) && linux - -package socket - -func (h *cmsghdr) set(l, lvl, typ int) { - h.Len = uint32(l) - h.Level = int32(lvl) - h.Type = int32(typ) -} diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go deleted file mode 100644 index 3ca0d3a0a..000000000 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux - -package socket - -func (h *cmsghdr) set(l, lvl, typ int) { - h.Len = uint64(l) - h.Level = int32(lvl) - h.Type = int32(typ) -} diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go deleted file mode 100644 index 6d0e426cd..000000000 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build amd64 && solaris - -package socket - -func (h *cmsghdr) set(l, lvl, typ int) { - h.Len = uint32(l) - h.Level = int32(lvl) - h.Type = int32(typ) -} diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go deleted file mode 100644 index 7ca9cb7e7..000000000 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos - -package socket - -func controlHeaderLen() int { - return 0 -} - -func controlMessageLen(dataLen int) int { - return 0 -} - -func controlMessageSpace(dataLen int) int { - return 0 -} - -type cmsghdr struct{} - -func (h *cmsghdr) len() int { return 0 } -func (h *cmsghdr) lvl() int { return 0 } -func (h *cmsghdr) typ() int { return 0 } - -func (h *cmsghdr) set(l, lvl, typ int) {} diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go deleted file mode 100644 index 0211f225b..000000000 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_unix.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos - -package socket - -import "golang.org/x/sys/unix" - -func controlHeaderLen() int { - return unix.CmsgLen(0) -} - -func controlMessageLen(dataLen int) int { - return unix.CmsgLen(dataLen) -} - -func controlMessageSpace(dataLen int) int { - return unix.CmsgSpace(dataLen) -} diff --git a/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go deleted file mode 100644 index 68dc8ad63..000000000 --- a/vendor/golang.org/x/net/internal/socket/cmsghdr_zos_s390x.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -func (h *cmsghdr) set(l, lvl, typ int) { - h.Len = int32(l) - h.Level = int32(lvl) - h.Type = int32(typ) -} diff --git a/vendor/golang.org/x/net/internal/socket/complete_dontwait.go b/vendor/golang.org/x/net/internal/socket/complete_dontwait.go deleted file mode 100644 index 2038f2904..000000000 --- a/vendor/golang.org/x/net/internal/socket/complete_dontwait.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris - -package socket - -import ( - "syscall" -) - -// ioComplete checks the flags and result of a syscall, to be used as return -// value in a syscall.RawConn.Read or Write callback. -func ioComplete(flags int, operr error) bool { - if flags&syscall.MSG_DONTWAIT != 0 { - // Caller explicitly said don't wait, so always return immediately. - return true - } - if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK { - // No data available, block for I/O and try again. - return false - } - return true -} diff --git a/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go b/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go deleted file mode 100644 index 70e6f448b..000000000 --- a/vendor/golang.org/x/net/internal/socket/complete_nodontwait.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || windows || zos - -package socket - -import ( - "syscall" -) - -// ioComplete checks the flags and result of a syscall, to be used as return -// value in a syscall.RawConn.Read or Write callback. -func ioComplete(flags int, operr error) bool { - if operr == syscall.EAGAIN || operr == syscall.EWOULDBLOCK { - // No data available, block for I/O and try again. - return false - } - return true -} diff --git a/vendor/golang.org/x/net/internal/socket/empty.s b/vendor/golang.org/x/net/internal/socket/empty.s deleted file mode 100644 index 49d79791e..000000000 --- a/vendor/golang.org/x/net/internal/socket/empty.s +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build darwin && go1.12 - -// This exists solely so we can linkname in symbols from syscall. diff --git a/vendor/golang.org/x/net/internal/socket/error_unix.go b/vendor/golang.org/x/net/internal/socket/error_unix.go deleted file mode 100644 index 7a5cc5c43..000000000 --- a/vendor/golang.org/x/net/internal/socket/error_unix.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos - -package socket - -import "syscall" - -var ( - errEAGAIN error = syscall.EAGAIN - errEINVAL error = syscall.EINVAL - errENOENT error = syscall.ENOENT -) - -// errnoErr returns common boxed Errno values, to prevent allocations -// at runtime. -func errnoErr(errno syscall.Errno) error { - switch errno { - case 0: - return nil - case syscall.EAGAIN: - return errEAGAIN - case syscall.EINVAL: - return errEINVAL - case syscall.ENOENT: - return errENOENT - } - return errno -} diff --git a/vendor/golang.org/x/net/internal/socket/error_windows.go b/vendor/golang.org/x/net/internal/socket/error_windows.go deleted file mode 100644 index 6a6379a8b..000000000 --- a/vendor/golang.org/x/net/internal/socket/error_windows.go +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import "syscall" - -var ( - errERROR_IO_PENDING error = syscall.ERROR_IO_PENDING - errEINVAL error = syscall.EINVAL -) - -// errnoErr returns common boxed Errno values, to prevent allocations -// at runtime. -func errnoErr(errno syscall.Errno) error { - switch errno { - case 0: - return nil - case syscall.ERROR_IO_PENDING: - return errERROR_IO_PENDING - case syscall.EINVAL: - return errEINVAL - } - return errno -} diff --git a/vendor/golang.org/x/net/internal/socket/iovec_32bit.go b/vendor/golang.org/x/net/internal/socket/iovec_32bit.go deleted file mode 100644 index 340e53fbd..000000000 --- a/vendor/golang.org/x/net/internal/socket/iovec_32bit.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (arm || mips || mipsle || 386 || ppc) && (darwin || dragonfly || freebsd || linux || netbsd || openbsd) - -package socket - -import "unsafe" - -func (v *iovec) set(b []byte) { - l := len(b) - if l == 0 { - return - } - v.Base = (*byte)(unsafe.Pointer(&b[0])) - v.Len = uint32(l) -} diff --git a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_64bit.go deleted file mode 100644 index 26470c191..000000000 --- a/vendor/golang.org/x/net/internal/socket/iovec_64bit.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || zos) - -package socket - -import "unsafe" - -func (v *iovec) set(b []byte) { - l := len(b) - if l == 0 { - return - } - v.Base = (*byte)(unsafe.Pointer(&b[0])) - v.Len = uint64(l) -} diff --git a/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go deleted file mode 100644 index 8859ce103..000000000 --- a/vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build amd64 && solaris - -package socket - -import "unsafe" - -func (v *iovec) set(b []byte) { - l := len(b) - if l == 0 { - return - } - v.Base = (*int8)(unsafe.Pointer(&b[0])) - v.Len = uint64(l) -} diff --git a/vendor/golang.org/x/net/internal/socket/iovec_stub.go b/vendor/golang.org/x/net/internal/socket/iovec_stub.go deleted file mode 100644 index da886b032..000000000 --- a/vendor/golang.org/x/net/internal/socket/iovec_stub.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos - -package socket - -type iovec struct{} - -func (v *iovec) set(b []byte) {} diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go deleted file mode 100644 index 4825b21e3..000000000 --- a/vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !aix && !linux && !netbsd - -package socket - -import "net" - -type mmsghdr struct{} - -type mmsghdrs []mmsghdr - -func (hs mmsghdrs) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr) []byte) error { - return nil -} - -func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error { - return nil -} diff --git a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go b/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go deleted file mode 100644 index 311fd2c78..000000000 --- a/vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || linux || netbsd - -package socket - -import ( - "net" - "os" - "sync" - "syscall" -) - -type mmsghdrs []mmsghdr - -func (hs mmsghdrs) unpack(ms []Message, parseFn func([]byte, string) (net.Addr, error), hint string) error { - for i := range hs { - ms[i].N = int(hs[i].Len) - ms[i].NN = hs[i].Hdr.controllen() - ms[i].Flags = hs[i].Hdr.flags() - if parseFn != nil { - var err error - ms[i].Addr, err = parseFn(hs[i].Hdr.name(), hint) - if err != nil { - return err - } - } - } - return nil -} - -// mmsghdrsPacker packs Message-slices into mmsghdrs (re-)using pre-allocated buffers. -type mmsghdrsPacker struct { - // hs are the pre-allocated mmsghdrs. - hs mmsghdrs - // sockaddrs is the pre-allocated buffer for the Hdr.Name buffers. - // We use one large buffer for all messages and slice it up. - sockaddrs []byte - // vs are the pre-allocated iovecs. - // We allocate one large buffer for all messages and slice it up. This allows to reuse the buffer - // if the number of buffers per message is distributed differently between calls. - vs []iovec -} - -func (p *mmsghdrsPacker) prepare(ms []Message) { - n := len(ms) - if n <= cap(p.hs) { - p.hs = p.hs[:n] - } else { - p.hs = make(mmsghdrs, n) - } - if n*sizeofSockaddrInet6 <= cap(p.sockaddrs) { - p.sockaddrs = p.sockaddrs[:n*sizeofSockaddrInet6] - } else { - p.sockaddrs = make([]byte, n*sizeofSockaddrInet6) - } - - nb := 0 - for _, m := range ms { - nb += len(m.Buffers) - } - if nb <= cap(p.vs) { - p.vs = p.vs[:nb] - } else { - p.vs = make([]iovec, nb) - } -} - -func (p *mmsghdrsPacker) pack(ms []Message, parseFn func([]byte, string) (net.Addr, error), marshalFn func(net.Addr, []byte) int) mmsghdrs { - p.prepare(ms) - hs := p.hs - vsRest := p.vs - saRest := p.sockaddrs - for i := range hs { - nvs := len(ms[i].Buffers) - vs := vsRest[:nvs] - vsRest = vsRest[nvs:] - - var sa []byte - if parseFn != nil { - sa = saRest[:sizeofSockaddrInet6] - saRest = saRest[sizeofSockaddrInet6:] - } else if marshalFn != nil { - n := marshalFn(ms[i].Addr, saRest) - if n > 0 { - sa = saRest[:n] - saRest = saRest[n:] - } - } - hs[i].Hdr.pack(vs, ms[i].Buffers, ms[i].OOB, sa) - } - return hs -} - -// syscaller is a helper to invoke recvmmsg and sendmmsg via the RawConn.Read/Write interface. -// It is reusable, to amortize the overhead of allocating a closure for the function passed to -// RawConn.Read/Write. -type syscaller struct { - n int - operr error - hs mmsghdrs - flags int - - boundRecvmmsgF func(uintptr) bool - boundSendmmsgF func(uintptr) bool -} - -func (r *syscaller) init() { - r.boundRecvmmsgF = r.recvmmsgF - r.boundSendmmsgF = r.sendmmsgF -} - -func (r *syscaller) recvmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) { - r.n = 0 - r.operr = nil - r.hs = hs - r.flags = flags - if err := c.Read(r.boundRecvmmsgF); err != nil { - return r.n, err - } - if r.operr != nil { - return r.n, os.NewSyscallError("recvmmsg", r.operr) - } - return r.n, nil -} - -func (r *syscaller) recvmmsgF(s uintptr) bool { - r.n, r.operr = recvmmsg(s, r.hs, r.flags) - return ioComplete(r.flags, r.operr) -} - -func (r *syscaller) sendmmsg(c syscall.RawConn, hs mmsghdrs, flags int) (int, error) { - r.n = 0 - r.operr = nil - r.hs = hs - r.flags = flags - if err := c.Write(r.boundSendmmsgF); err != nil { - return r.n, err - } - if r.operr != nil { - return r.n, os.NewSyscallError("sendmmsg", r.operr) - } - return r.n, nil -} - -func (r *syscaller) sendmmsgF(s uintptr) bool { - r.n, r.operr = sendmmsg(s, r.hs, r.flags) - return ioComplete(r.flags, r.operr) -} - -// mmsgTmps holds reusable temporary helpers for recvmmsg and sendmmsg. -type mmsgTmps struct { - packer mmsghdrsPacker - syscaller syscaller -} - -var defaultMmsgTmpsPool = mmsgTmpsPool{ - p: sync.Pool{ - New: func() interface{} { - tmps := new(mmsgTmps) - tmps.syscaller.init() - return tmps - }, - }, -} - -type mmsgTmpsPool struct { - p sync.Pool -} - -func (p *mmsgTmpsPool) Get() *mmsgTmps { - m := p.p.Get().(*mmsgTmps) - // Clear fields up to the len (not the cap) of the slice, - // assuming that the previous caller only used that many elements. - for i := range m.packer.sockaddrs { - m.packer.sockaddrs[i] = 0 - } - m.packer.sockaddrs = m.packer.sockaddrs[:0] - for i := range m.packer.vs { - m.packer.vs[i] = iovec{} - } - m.packer.vs = m.packer.vs[:0] - for i := range m.packer.hs { - m.packer.hs[i].Len = 0 - m.packer.hs[i].Hdr = msghdr{} - } - m.packer.hs = m.packer.hs[:0] - return m -} - -func (p *mmsgTmpsPool) Put(tmps *mmsgTmps) { - p.p.Put(tmps) -} diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go deleted file mode 100644 index ebff4f6e0..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_bsd.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd - -package socket - -import "unsafe" - -func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) { - for i := range vs { - vs[i].set(bs[i]) - } - h.setIov(vs) - if len(oob) > 0 { - h.Control = (*byte)(unsafe.Pointer(&oob[0])) - h.Controllen = uint32(len(oob)) - } - if sa != nil { - h.Name = (*byte)(unsafe.Pointer(&sa[0])) - h.Namelen = uint32(len(sa)) - } -} - -func (h *msghdr) name() []byte { - if h.Name != nil && h.Namelen > 0 { - return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen] - } - return nil -} - -func (h *msghdr) controllen() int { - return int(h.Controllen) -} - -func (h *msghdr) flags() int { - return int(h.Flags) -} diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go b/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go deleted file mode 100644 index 62e6fe861..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || netbsd - -package socket - -func (h *msghdr) setIov(vs []iovec) { - l := len(vs) - if l == 0 { - return - } - h.Iov = &vs[0] - h.Iovlen = int32(l) -} diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux.go deleted file mode 100644 index 5a38798cc..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_linux.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import "unsafe" - -func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) { - for i := range vs { - vs[i].set(bs[i]) - } - h.setIov(vs) - if len(oob) > 0 { - h.setControl(oob) - } - if sa != nil { - h.Name = (*byte)(unsafe.Pointer(&sa[0])) - h.Namelen = uint32(len(sa)) - } -} - -func (h *msghdr) name() []byte { - if h.Name != nil && h.Namelen > 0 { - return (*[sizeofSockaddrInet6]byte)(unsafe.Pointer(h.Name))[:h.Namelen] - } - return nil -} - -func (h *msghdr) controllen() int { - return int(h.Controllen) -} - -func (h *msghdr) flags() int { - return int(h.Flags) -} diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go deleted file mode 100644 index 3dd07250a..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (arm || mips || mipsle || 386 || ppc) && linux - -package socket - -import "unsafe" - -func (h *msghdr) setIov(vs []iovec) { - l := len(vs) - if l == 0 { - return - } - h.Iov = &vs[0] - h.Iovlen = uint32(l) -} - -func (h *msghdr) setControl(b []byte) { - h.Control = (*byte)(unsafe.Pointer(&b[0])) - h.Controllen = uint32(len(b)) -} diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go deleted file mode 100644 index 5af9ddd6a..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build (arm64 || amd64 || loong64 || ppc64 || ppc64le || mips64 || mips64le || riscv64 || s390x) && linux - -package socket - -import "unsafe" - -func (h *msghdr) setIov(vs []iovec) { - l := len(vs) - if l == 0 { - return - } - h.Iov = &vs[0] - h.Iovlen = uint64(l) -} - -func (h *msghdr) setControl(b []byte) { - h.Control = (*byte)(unsafe.Pointer(&b[0])) - h.Controllen = uint64(len(b)) -} diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go b/vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go deleted file mode 100644 index 71a69e251..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -func (h *msghdr) setIov(vs []iovec) { - l := len(vs) - if l == 0 { - return - } - h.Iov = &vs[0] - h.Iovlen = uint32(l) -} diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go b/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go deleted file mode 100644 index e212b50f8..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build amd64 && solaris - -package socket - -import "unsafe" - -func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) { - for i := range vs { - vs[i].set(bs[i]) - } - if len(vs) > 0 { - h.Iov = &vs[0] - h.Iovlen = int32(len(vs)) - } - if len(oob) > 0 { - h.Accrights = (*int8)(unsafe.Pointer(&oob[0])) - h.Accrightslen = int32(len(oob)) - } - if sa != nil { - h.Name = (*byte)(unsafe.Pointer(&sa[0])) - h.Namelen = uint32(len(sa)) - } -} - -func (h *msghdr) controllen() int { - return int(h.Accrightslen) -} - -func (h *msghdr) flags() int { - return int(NativeEndian.Uint32(h.Pad_cgo_2[:])) -} diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go b/vendor/golang.org/x/net/internal/socket/msghdr_stub.go deleted file mode 100644 index e87677645..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_stub.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos - -package socket - -type msghdr struct{} - -func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) {} -func (h *msghdr) name() []byte { return nil } -func (h *msghdr) controllen() int { return 0 } -func (h *msghdr) flags() int { return 0 } diff --git a/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go deleted file mode 100644 index 529db68ee..000000000 --- a/vendor/golang.org/x/net/internal/socket/msghdr_zos_s390x.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build s390x && zos - -package socket - -import "unsafe" - -func (h *msghdr) pack(vs []iovec, bs [][]byte, oob []byte, sa []byte) { - for i := range vs { - vs[i].set(bs[i]) - } - if len(vs) > 0 { - h.Iov = &vs[0] - h.Iovlen = int32(len(vs)) - } - if len(oob) > 0 { - h.Control = (*byte)(unsafe.Pointer(&oob[0])) - h.Controllen = uint32(len(oob)) - } - if sa != nil { - h.Name = (*byte)(unsafe.Pointer(&sa[0])) - h.Namelen = uint32(len(sa)) - } -} - -func (h *msghdr) controllen() int { - return int(h.Controllen) -} - -func (h *msghdr) flags() int { - return int(h.Flags) -} diff --git a/vendor/golang.org/x/net/internal/socket/norace.go b/vendor/golang.org/x/net/internal/socket/norace.go deleted file mode 100644 index 8af30ecfb..000000000 --- a/vendor/golang.org/x/net/internal/socket/norace.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !race - -package socket - -func (m *Message) raceRead() { -} -func (m *Message) raceWrite() { -} diff --git a/vendor/golang.org/x/net/internal/socket/race.go b/vendor/golang.org/x/net/internal/socket/race.go deleted file mode 100644 index 9afa95808..000000000 --- a/vendor/golang.org/x/net/internal/socket/race.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build race - -package socket - -import ( - "runtime" - "unsafe" -) - -// This package reads and writes the Message buffers using a -// direct system call, which the race detector can't see. -// These functions tell the race detector what is going on during the syscall. - -func (m *Message) raceRead() { - for _, b := range m.Buffers { - if len(b) > 0 { - runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b)) - } - } - if b := m.OOB; len(b) > 0 { - runtime.RaceReadRange(unsafe.Pointer(&b[0]), len(b)) - } -} -func (m *Message) raceWrite() { - for _, b := range m.Buffers { - if len(b) > 0 { - runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b)) - } - } - if b := m.OOB; len(b) > 0 { - runtime.RaceWriteRange(unsafe.Pointer(&b[0]), len(b)) - } -} diff --git a/vendor/golang.org/x/net/internal/socket/rawconn.go b/vendor/golang.org/x/net/internal/socket/rawconn.go deleted file mode 100644 index 87e81071c..000000000 --- a/vendor/golang.org/x/net/internal/socket/rawconn.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import ( - "errors" - "net" - "os" - "syscall" -) - -// A Conn represents a raw connection. -type Conn struct { - network string - c syscall.RawConn -} - -// tcpConn is an interface implemented by net.TCPConn. -// It can be used for interface assertions to check if a net.Conn is a TCP connection. -type tcpConn interface { - SyscallConn() (syscall.RawConn, error) - SetLinger(int) error -} - -var _ tcpConn = (*net.TCPConn)(nil) - -// udpConn is an interface implemented by net.UDPConn. -// It can be used for interface assertions to check if a net.Conn is a UDP connection. -type udpConn interface { - SyscallConn() (syscall.RawConn, error) - ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error) -} - -var _ udpConn = (*net.UDPConn)(nil) - -// ipConn is an interface implemented by net.IPConn. -// It can be used for interface assertions to check if a net.Conn is an IP connection. -type ipConn interface { - SyscallConn() (syscall.RawConn, error) - ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *net.IPAddr, err error) -} - -var _ ipConn = (*net.IPConn)(nil) - -// NewConn returns a new raw connection. -func NewConn(c net.Conn) (*Conn, error) { - var err error - var cc Conn - switch c := c.(type) { - case tcpConn: - cc.network = "tcp" - cc.c, err = c.SyscallConn() - case udpConn: - cc.network = "udp" - cc.c, err = c.SyscallConn() - case ipConn: - cc.network = "ip" - cc.c, err = c.SyscallConn() - default: - return nil, errors.New("unknown connection type") - } - if err != nil { - return nil, err - } - return &cc, nil -} - -func (o *Option) get(c *Conn, b []byte) (int, error) { - var operr error - var n int - fn := func(s uintptr) { - n, operr = getsockopt(s, o.Level, o.Name, b) - } - if err := c.c.Control(fn); err != nil { - return 0, err - } - return n, os.NewSyscallError("getsockopt", operr) -} - -func (o *Option) set(c *Conn, b []byte) error { - var operr error - fn := func(s uintptr) { - operr = setsockopt(s, o.Level, o.Name, b) - } - if err := c.c.Control(fn); err != nil { - return err - } - return os.NewSyscallError("setsockopt", operr) -} diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go deleted file mode 100644 index 043139078..000000000 --- a/vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build linux - -package socket - -import ( - "net" -) - -func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) { - for i := range ms { - ms[i].raceWrite() - } - tmps := defaultMmsgTmpsPool.Get() - defer defaultMmsgTmpsPool.Put(tmps) - var parseFn func([]byte, string) (net.Addr, error) - if c.network != "tcp" { - parseFn = parseInetAddr - } - hs := tmps.packer.pack(ms, parseFn, nil) - n, err := tmps.syscaller.recvmmsg(c.c, hs, flags) - if err != nil { - return n, err - } - if err := hs[:n].unpack(ms[:n], parseFn, c.network); err != nil { - return n, err - } - return n, nil -} - -func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) { - for i := range ms { - ms[i].raceRead() - } - tmps := defaultMmsgTmpsPool.Get() - defer defaultMmsgTmpsPool.Put(tmps) - var marshalFn func(net.Addr, []byte) int - if c.network != "tcp" { - marshalFn = marshalInetAddr - } - hs := tmps.packer.pack(ms, nil, marshalFn) - n, err := tmps.syscaller.sendmmsg(c.c, hs, flags) - if err != nil { - return n, err - } - if err := hs[:n].unpack(ms[:n], nil, ""); err != nil { - return n, err - } - return n, nil -} diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go deleted file mode 100644 index 7c0d7410b..000000000 --- a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos - -package socket - -import ( - "net" - "os" -) - -func (c *Conn) recvMsg(m *Message, flags int) error { - m.raceWrite() - var ( - operr error - n int - oobn int - recvflags int - from net.Addr - ) - fn := func(s uintptr) bool { - n, oobn, recvflags, from, operr = recvmsg(s, m.Buffers, m.OOB, flags, c.network) - return ioComplete(flags, operr) - } - if err := c.c.Read(fn); err != nil { - return err - } - if operr != nil { - return os.NewSyscallError("recvmsg", operr) - } - m.Addr = from - m.N = n - m.NN = oobn - m.Flags = recvflags - return nil -} - -func (c *Conn) sendMsg(m *Message, flags int) error { - m.raceRead() - var ( - operr error - n int - ) - fn := func(s uintptr) bool { - n, operr = sendmsg(s, m.Buffers, m.OOB, m.Addr, flags) - return ioComplete(flags, operr) - } - if err := c.c.Write(fn); err != nil { - return err - } - if operr != nil { - return os.NewSyscallError("sendmsg", operr) - } - m.N = n - m.NN = len(m.OOB) - return nil -} diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go deleted file mode 100644 index e363fb5a8..000000000 --- a/vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !linux - -package socket - -func (c *Conn) recvMsgs(ms []Message, flags int) (int, error) { - return 0, errNotImplemented -} - -func (c *Conn) sendMsgs(ms []Message, flags int) (int, error) { - return 0, errNotImplemented -} diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go b/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go deleted file mode 100644 index ff7a8baf0..000000000 --- a/vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos - -package socket - -func (c *Conn) recvMsg(m *Message, flags int) error { - return errNotImplemented -} - -func (c *Conn) sendMsg(m *Message, flags int) error { - return errNotImplemented -} diff --git a/vendor/golang.org/x/net/internal/socket/socket.go b/vendor/golang.org/x/net/internal/socket/socket.go deleted file mode 100644 index dba47bf12..000000000 --- a/vendor/golang.org/x/net/internal/socket/socket.go +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package socket provides a portable interface for socket system -// calls. -package socket // import "golang.org/x/net/internal/socket" - -import ( - "errors" - "net" - "runtime" - "unsafe" -) - -var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH) - -// An Option represents a sticky socket option. -type Option struct { - Level int // level - Name int // name; must be equal or greater than 1 - Len int // length of value in bytes; must be equal or greater than 1 -} - -// Get reads a value for the option from the kernel. -// It returns the number of bytes written into b. -func (o *Option) Get(c *Conn, b []byte) (int, error) { - if o.Name < 1 || o.Len < 1 { - return 0, errors.New("invalid option") - } - if len(b) < o.Len { - return 0, errors.New("short buffer") - } - return o.get(c, b) -} - -// GetInt returns an integer value for the option. -// -// The Len field of Option must be either 1 or 4. -func (o *Option) GetInt(c *Conn) (int, error) { - if o.Len != 1 && o.Len != 4 { - return 0, errors.New("invalid option") - } - var b []byte - var bb [4]byte - if o.Len == 1 { - b = bb[:1] - } else { - b = bb[:4] - } - n, err := o.get(c, b) - if err != nil { - return 0, err - } - if n != o.Len { - return 0, errors.New("invalid option length") - } - if o.Len == 1 { - return int(b[0]), nil - } - return int(NativeEndian.Uint32(b[:4])), nil -} - -// Set writes the option and value to the kernel. -func (o *Option) Set(c *Conn, b []byte) error { - if o.Name < 1 || o.Len < 1 { - return errors.New("invalid option") - } - if len(b) < o.Len { - return errors.New("short buffer") - } - return o.set(c, b) -} - -// SetInt writes the option and value to the kernel. -// -// The Len field of Option must be either 1 or 4. -func (o *Option) SetInt(c *Conn, v int) error { - if o.Len != 1 && o.Len != 4 { - return errors.New("invalid option") - } - var b []byte - if o.Len == 1 { - b = []byte{byte(v)} - } else { - var bb [4]byte - NativeEndian.PutUint32(bb[:o.Len], uint32(v)) - b = bb[:4] - } - return o.set(c, b) -} - -// ControlMessageSpace returns the whole length of control message. -func ControlMessageSpace(dataLen int) int { - return controlMessageSpace(dataLen) -} - -// A ControlMessage represents the head message in a stream of control -// messages. -// -// A control message comprises of a header, data and a few padding -// fields to conform to the interface to the kernel. -// -// See RFC 3542 for further information. -type ControlMessage []byte - -// Data returns the data field of the control message at the head on -// m. -func (m ControlMessage) Data(dataLen int) []byte { - l := controlHeaderLen() - if len(m) < l || len(m) < l+dataLen { - return nil - } - return m[l : l+dataLen] -} - -// Next returns the control message at the next on m. -// -// Next works only for standard control messages. -func (m ControlMessage) Next(dataLen int) ControlMessage { - l := ControlMessageSpace(dataLen) - if len(m) < l { - return nil - } - return m[l:] -} - -// MarshalHeader marshals the header fields of the control message at -// the head on m. -func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error { - if len(m) < controlHeaderLen() { - return errors.New("short message") - } - h := (*cmsghdr)(unsafe.Pointer(&m[0])) - h.set(controlMessageLen(dataLen), lvl, typ) - return nil -} - -// ParseHeader parses and returns the header fields of the control -// message at the head on m. -func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) { - l := controlHeaderLen() - if len(m) < l { - return 0, 0, 0, errors.New("short message") - } - h := (*cmsghdr)(unsafe.Pointer(&m[0])) - return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil -} - -// Marshal marshals the control message at the head on m, and returns -// the next control message. -func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) { - l := len(data) - if len(m) < ControlMessageSpace(l) { - return nil, errors.New("short message") - } - h := (*cmsghdr)(unsafe.Pointer(&m[0])) - h.set(controlMessageLen(l), lvl, typ) - if l > 0 { - copy(m.Data(l), data) - } - return m.Next(l), nil -} - -// Parse parses m as a single or multiple control messages. -// -// Parse works for both standard and compatible messages. -func (m ControlMessage) Parse() ([]ControlMessage, error) { - var ms []ControlMessage - for len(m) >= controlHeaderLen() { - h := (*cmsghdr)(unsafe.Pointer(&m[0])) - l := h.len() - if l <= 0 { - return nil, errors.New("invalid header length") - } - if uint64(l) < uint64(controlHeaderLen()) { - return nil, errors.New("invalid message length") - } - if uint64(l) > uint64(len(m)) { - return nil, errors.New("short buffer") - } - // On message reception: - // - // |<- ControlMessageSpace --------------->| - // |<- controlMessageLen ---------->| | - // |<- controlHeaderLen ->| | | - // +---------------+------+---------+------+ - // | Header | PadH | Data | PadD | - // +---------------+------+---------+------+ - // - // On compatible message reception: - // - // | ... |<- controlMessageLen ----------->| - // | ... |<- controlHeaderLen ->| | - // +-----+---------------+------+----------+ - // | ... | Header | PadH | Data | - // +-----+---------------+------+----------+ - ms = append(ms, ControlMessage(m[:l])) - ll := l - controlHeaderLen() - if len(m) >= ControlMessageSpace(ll) { - m = m[ControlMessageSpace(ll):] - } else { - m = m[controlMessageLen(ll):] - } - } - return ms, nil -} - -// NewControlMessage returns a new stream of control messages. -func NewControlMessage(dataLen []int) ControlMessage { - var l int - for i := range dataLen { - l += ControlMessageSpace(dataLen[i]) - } - return make([]byte, l) -} - -// A Message represents an IO message. -type Message struct { - // When writing, the Buffers field must contain at least one - // byte to write. - // When reading, the Buffers field will always contain a byte - // to read. - Buffers [][]byte - - // OOB contains protocol-specific control or miscellaneous - // ancillary data known as out-of-band data. - OOB []byte - - // Addr specifies a destination address when writing. - // It can be nil when the underlying protocol of the raw - // connection uses connection-oriented communication. - // After a successful read, it may contain the source address - // on the received packet. - Addr net.Addr - - N int // # of bytes read or written from/to Buffers - NN int // # of bytes read or written from/to OOB - Flags int // protocol-specific information on the received message -} - -// RecvMsg wraps recvmsg system call. -// -// The provided flags is a set of platform-dependent flags, such as -// syscall.MSG_PEEK. -func (c *Conn) RecvMsg(m *Message, flags int) error { - return c.recvMsg(m, flags) -} - -// SendMsg wraps sendmsg system call. -// -// The provided flags is a set of platform-dependent flags, such as -// syscall.MSG_DONTROUTE. -func (c *Conn) SendMsg(m *Message, flags int) error { - return c.sendMsg(m, flags) -} - -// RecvMsgs wraps recvmmsg system call. -// -// It returns the number of processed messages. -// -// The provided flags is a set of platform-dependent flags, such as -// syscall.MSG_PEEK. -// -// Only Linux supports this. -func (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) { - return c.recvMsgs(ms, flags) -} - -// SendMsgs wraps sendmmsg system call. -// -// It returns the number of processed messages. -// -// The provided flags is a set of platform-dependent flags, such as -// syscall.MSG_DONTROUTE. -// -// Only Linux supports this. -func (c *Conn) SendMsgs(ms []Message, flags int) (int, error) { - return c.sendMsgs(ms, flags) -} diff --git a/vendor/golang.org/x/net/internal/socket/sys.go b/vendor/golang.org/x/net/internal/socket/sys.go deleted file mode 100644 index 4a26af186..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import ( - "encoding/binary" - "unsafe" -) - -// NativeEndian is the machine native endian implementation of ByteOrder. -var NativeEndian binary.ByteOrder - -func init() { - i := uint32(1) - b := (*[4]byte)(unsafe.Pointer(&i)) - if b[0] == 1 { - NativeEndian = binary.LittleEndian - } else { - NativeEndian = binary.BigEndian - } -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_bsd.go b/vendor/golang.org/x/net/internal/socket/sys_bsd.go deleted file mode 100644 index e7664d48b..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_bsd.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris - -package socket - -func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errNotImplemented -} - -func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errNotImplemented -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_const_unix.go b/vendor/golang.org/x/net/internal/socket/sys_const_unix.go deleted file mode 100644 index d7627f87e..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_const_unix.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos - -package socket - -import "golang.org/x/sys/unix" - -const ( - sysAF_UNSPEC = unix.AF_UNSPEC - sysAF_INET = unix.AF_INET - sysAF_INET6 = unix.AF_INET6 - - sysSOCK_RAW = unix.SOCK_RAW - - sizeofSockaddrInet4 = unix.SizeofSockaddrInet4 - sizeofSockaddrInet6 = unix.SizeofSockaddrInet6 -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux.go b/vendor/golang.org/x/net/internal/socket/sys_linux.go deleted file mode 100644 index 08d491077..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build linux && !s390x && !386 - -package socket - -import ( - "syscall" - "unsafe" -) - -func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - n, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) - return int(n), errnoErr(errno) -} - -func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - n, _, errno := syscall.Syscall6(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) - return int(n), errnoErr(errno) -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_386.go b/vendor/golang.org/x/net/internal/socket/sys_linux_386.go deleted file mode 100644 index c877ef23a..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_386.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import ( - "syscall" - "unsafe" -) - -const ( - sysRECVMMSG = 0x13 - sysSENDMMSG = 0x14 -) - -func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno) -func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno) - -func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) - return int(n), errnoErr(errno) -} - -func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - n, errno := socketcall(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) - return int(n), errnoErr(errno) -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_386.s b/vendor/golang.org/x/net/internal/socket/sys_linux_386.s deleted file mode 100644 index 93e7d75ec..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_386.s +++ /dev/null @@ -1,11 +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. - -#include "textflag.h" - -TEXT ·socketcall(SB),NOSPLIT,$0-36 - JMP syscall·socketcall(SB) - -TEXT ·rawsocketcall(SB),NOSPLIT,$0-36 - JMP syscall·rawsocketcall(SB) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go deleted file mode 100644 index 9decee2e5..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x12b - sysSENDMMSG = 0x133 -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_arm.go b/vendor/golang.org/x/net/internal/socket/sys_linux_arm.go deleted file mode 100644 index d753b436d..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_arm.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x16d - sysSENDMMSG = 0x176 -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go deleted file mode 100644 index b67089436..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0xf3 - sysSENDMMSG = 0x10d -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go deleted file mode 100644 index 1d182470d..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_loong64.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build loong64 - -package socket - -const ( - sysRECVMMSG = 0xf3 - sysSENDMMSG = 0x10d -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_mips.go b/vendor/golang.org/x/net/internal/socket/sys_linux_mips.go deleted file mode 100644 index 9c0d74014..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_mips.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x10ef - sysSENDMMSG = 0x10f7 -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go deleted file mode 100644 index 071a4aba8..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x14ae - sysSENDMMSG = 0x14b6 -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go b/vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go deleted file mode 100644 index 071a4aba8..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x14ae - sysSENDMMSG = 0x14b6 -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go b/vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go deleted file mode 100644 index 9c0d74014..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x10ef - sysSENDMMSG = 0x10f7 -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go b/vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go deleted file mode 100644 index 90cfaa9fe..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x157 - sysSENDMMSG = 0x15d -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go deleted file mode 100644 index 21c1e3f00..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x157 - sysSENDMMSG = 0x15d -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go b/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go deleted file mode 100644 index 21c1e3f00..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -const ( - sysRECVMMSG = 0x157 - sysSENDMMSG = 0x15d -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go deleted file mode 100644 index 0e407d125..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build riscv64 - -package socket - -const ( - sysRECVMMSG = 0xf3 - sysSENDMMSG = 0x10d -) diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go deleted file mode 100644 index c877ef23a..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import ( - "syscall" - "unsafe" -) - -const ( - sysRECVMMSG = 0x13 - sysSENDMMSG = 0x14 -) - -func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno) -func rawsocketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno) - -func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - n, errno := socketcall(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) - return int(n), errnoErr(errno) -} - -func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - n, errno := socketcall(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) - return int(n), errnoErr(errno) -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s b/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s deleted file mode 100644 index 06d75628c..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" - -TEXT ·socketcall(SB),NOSPLIT,$0-72 - JMP syscall·socketcall(SB) - -TEXT ·rawsocketcall(SB),NOSPLIT,$0-72 - JMP syscall·rawsocketcall(SB) diff --git a/vendor/golang.org/x/net/internal/socket/sys_netbsd.go b/vendor/golang.org/x/net/internal/socket/sys_netbsd.go deleted file mode 100644 index 431851c12..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_netbsd.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import ( - "syscall" - "unsafe" -) - -const ( - sysRECVMMSG = 0x1db - sysSENDMMSG = 0x1dc -) - -func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - n, _, errno := syscall.Syscall6(sysRECVMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) - return int(n), errnoErr(errno) -} - -func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - n, _, errno := syscall.Syscall6(sysSENDMMSG, s, uintptr(unsafe.Pointer(&hs[0])), uintptr(len(hs)), uintptr(flags), 0, 0) - return int(n), errnoErr(errno) -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_posix.go b/vendor/golang.org/x/net/internal/socket/sys_posix.go deleted file mode 100644 index 58d865482..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_posix.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos - -package socket - -import ( - "encoding/binary" - "errors" - "net" - "runtime" - "strconv" - "sync" - "time" -) - -// marshalInetAddr writes a in sockaddr format into the buffer b. -// The buffer must be sufficiently large (sizeofSockaddrInet4/6). -// Returns the number of bytes written. -func marshalInetAddr(a net.Addr, b []byte) int { - switch a := a.(type) { - case *net.TCPAddr: - return marshalSockaddr(a.IP, a.Port, a.Zone, b) - case *net.UDPAddr: - return marshalSockaddr(a.IP, a.Port, a.Zone, b) - case *net.IPAddr: - return marshalSockaddr(a.IP, 0, a.Zone, b) - default: - return 0 - } -} - -func marshalSockaddr(ip net.IP, port int, zone string, b []byte) int { - if ip4 := ip.To4(); ip4 != nil { - switch runtime.GOOS { - case "android", "illumos", "linux", "solaris", "windows": - NativeEndian.PutUint16(b[:2], uint16(sysAF_INET)) - default: - b[0] = sizeofSockaddrInet4 - b[1] = sysAF_INET - } - binary.BigEndian.PutUint16(b[2:4], uint16(port)) - copy(b[4:8], ip4) - return sizeofSockaddrInet4 - } - if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil { - switch runtime.GOOS { - case "android", "illumos", "linux", "solaris", "windows": - NativeEndian.PutUint16(b[:2], uint16(sysAF_INET6)) - default: - b[0] = sizeofSockaddrInet6 - b[1] = sysAF_INET6 - } - binary.BigEndian.PutUint16(b[2:4], uint16(port)) - copy(b[8:24], ip6) - if zone != "" { - NativeEndian.PutUint32(b[24:28], uint32(zoneCache.index(zone))) - } - return sizeofSockaddrInet6 - } - return 0 -} - -func parseInetAddr(b []byte, network string) (net.Addr, error) { - if len(b) < 2 { - return nil, errors.New("invalid address") - } - var af int - switch runtime.GOOS { - case "android", "illumos", "linux", "solaris", "windows": - af = int(NativeEndian.Uint16(b[:2])) - default: - af = int(b[1]) - } - var ip net.IP - var zone string - if af == sysAF_INET { - if len(b) < sizeofSockaddrInet4 { - return nil, errors.New("short address") - } - ip = make(net.IP, net.IPv4len) - copy(ip, b[4:8]) - } - if af == sysAF_INET6 { - if len(b) < sizeofSockaddrInet6 { - return nil, errors.New("short address") - } - ip = make(net.IP, net.IPv6len) - copy(ip, b[8:24]) - if id := int(NativeEndian.Uint32(b[24:28])); id > 0 { - zone = zoneCache.name(id) - } - } - switch network { - case "tcp", "tcp4", "tcp6": - return &net.TCPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil - case "udp", "udp4", "udp6": - return &net.UDPAddr{IP: ip, Port: int(binary.BigEndian.Uint16(b[2:4])), Zone: zone}, nil - default: - return &net.IPAddr{IP: ip, Zone: zone}, nil - } -} - -// An ipv6ZoneCache represents a cache holding partial network -// interface information. It is used for reducing the cost of IPv6 -// addressing scope zone resolution. -// -// Multiple names sharing the index are managed by first-come -// first-served basis for consistency. -type ipv6ZoneCache struct { - sync.RWMutex // guard the following - lastFetched time.Time // last time routing information was fetched - toIndex map[string]int // interface name to its index - toName map[int]string // interface index to its name -} - -var zoneCache = ipv6ZoneCache{ - toIndex: make(map[string]int), - toName: make(map[int]string), -} - -// update refreshes the network interface information if the cache was last -// updated more than 1 minute ago, or if force is set. It returns whether the -// cache was updated. -func (zc *ipv6ZoneCache) update(ift []net.Interface, force bool) (updated bool) { - zc.Lock() - defer zc.Unlock() - now := time.Now() - if !force && zc.lastFetched.After(now.Add(-60*time.Second)) { - return false - } - zc.lastFetched = now - if len(ift) == 0 { - var err error - if ift, err = net.Interfaces(); err != nil { - return false - } - } - zc.toIndex = make(map[string]int, len(ift)) - zc.toName = make(map[int]string, len(ift)) - for _, ifi := range ift { - zc.toIndex[ifi.Name] = ifi.Index - if _, ok := zc.toName[ifi.Index]; !ok { - zc.toName[ifi.Index] = ifi.Name - } - } - return true -} - -func (zc *ipv6ZoneCache) name(zone int) string { - updated := zoneCache.update(nil, false) - zoneCache.RLock() - name, ok := zoneCache.toName[zone] - zoneCache.RUnlock() - if !ok && !updated { - zoneCache.update(nil, true) - zoneCache.RLock() - name, ok = zoneCache.toName[zone] - zoneCache.RUnlock() - } - if !ok { // last resort - name = strconv.Itoa(zone) - } - return name -} - -func (zc *ipv6ZoneCache) index(zone string) int { - updated := zoneCache.update(nil, false) - zoneCache.RLock() - index, ok := zoneCache.toIndex[zone] - zoneCache.RUnlock() - if !ok && !updated { - zoneCache.update(nil, true) - zoneCache.RLock() - index, ok = zoneCache.toIndex[zone] - zoneCache.RUnlock() - } - if !ok { // last resort - index, _ = strconv.Atoi(zone) - } - return index -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_stub.go b/vendor/golang.org/x/net/internal/socket/sys_stub.go deleted file mode 100644 index 2e5b473c6..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_stub.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos - -package socket - -import "net" - -const ( - sysAF_UNSPEC = 0x0 - sysAF_INET = 0x2 - sysAF_INET6 = 0xa - - sysSOCK_RAW = 0x3 - - sizeofSockaddrInet4 = 0x10 - sizeofSockaddrInet6 = 0x1c -) - -func marshalInetAddr(ip net.IP, port int, zone string) []byte { - return nil -} - -func parseInetAddr(b []byte, network string) (net.Addr, error) { - return nil, errNotImplemented -} - -func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - return 0, errNotImplemented -} - -func setsockopt(s uintptr, level, name int, b []byte) error { - return errNotImplemented -} - -func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { - return 0, 0, 0, nil, errNotImplemented -} - -func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { - return 0, errNotImplemented -} - -func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errNotImplemented -} - -func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errNotImplemented -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go deleted file mode 100644 index 93058db5b..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_unix.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris - -package socket - -import ( - "net" - "unsafe" - - "golang.org/x/sys/unix" -) - -//go:linkname syscall_getsockopt syscall.getsockopt -func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) error - -//go:linkname syscall_setsockopt syscall.setsockopt -func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error - -func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - l := uint32(len(b)) - err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l) - return int(l), err -} - -func setsockopt(s uintptr, level, name int, b []byte) error { - return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b))) -} - -func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { - var unixFrom unix.Sockaddr - n, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags) - if unixFrom != nil { - from = sockaddrToAddr(unixFrom, network) - } - return -} - -func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { - var unixTo unix.Sockaddr - if to != nil { - unixTo = addrToSockaddr(to) - } - return unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags) -} - -// addrToSockaddr converts a net.Addr to a unix.Sockaddr. -func addrToSockaddr(a net.Addr) unix.Sockaddr { - var ( - ip net.IP - port int - zone string - ) - switch a := a.(type) { - case *net.TCPAddr: - ip = a.IP - port = a.Port - zone = a.Zone - case *net.UDPAddr: - ip = a.IP - port = a.Port - zone = a.Zone - case *net.IPAddr: - ip = a.IP - zone = a.Zone - default: - return nil - } - - if ip4 := ip.To4(); ip4 != nil { - sa := unix.SockaddrInet4{Port: port} - copy(sa.Addr[:], ip4) - return &sa - } - - if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil { - sa := unix.SockaddrInet6{Port: port} - copy(sa.Addr[:], ip6) - if zone != "" { - sa.ZoneId = uint32(zoneCache.index(zone)) - } - return &sa - } - - return nil -} - -// sockaddrToAddr converts a unix.Sockaddr to a net.Addr. -func sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr { - var ( - ip net.IP - port int - zone string - ) - switch sa := sa.(type) { - case *unix.SockaddrInet4: - ip = make(net.IP, net.IPv4len) - copy(ip, sa.Addr[:]) - port = sa.Port - case *unix.SockaddrInet6: - ip = make(net.IP, net.IPv6len) - copy(ip, sa.Addr[:]) - port = sa.Port - if sa.ZoneId > 0 { - zone = zoneCache.name(int(sa.ZoneId)) - } - default: - return nil - } - - switch network { - case "tcp", "tcp4", "tcp6": - return &net.TCPAddr{IP: ip, Port: port, Zone: zone} - case "udp", "udp4", "udp6": - return &net.UDPAddr{IP: ip, Port: port, Zone: zone} - default: - return &net.IPAddr{IP: ip, Zone: zone} - } -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_windows.go b/vendor/golang.org/x/net/internal/socket/sys_windows.go deleted file mode 100644 index b738b89dd..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_windows.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import ( - "net" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -func probeProtocolStack() int { - var p uintptr - return int(unsafe.Sizeof(p)) -} - -const ( - sysAF_UNSPEC = windows.AF_UNSPEC - sysAF_INET = windows.AF_INET - sysAF_INET6 = windows.AF_INET6 - - sysSOCK_RAW = windows.SOCK_RAW - - sizeofSockaddrInet4 = 0x10 - sizeofSockaddrInet6 = 0x1c -) - -func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - l := uint32(len(b)) - err := syscall.Getsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), (*int32)(unsafe.Pointer(&l))) - return int(l), err -} - -func setsockopt(s uintptr, level, name int, b []byte) error { - return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b))) -} - -func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { - return 0, 0, 0, nil, errNotImplemented -} - -func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { - return 0, errNotImplemented -} - -func recvmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errNotImplemented -} - -func sendmmsg(s uintptr, hs []mmsghdr, flags int) (int, error) { - return 0, errNotImplemented -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go deleted file mode 100644 index eaa896cb5..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -import ( - "net" - "syscall" - "unsafe" -) - -func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) -func syscall_syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) - -func probeProtocolStack() int { - return 4 // sizeof(int) on GOOS=zos GOARCH=s390x -} - -func getsockopt(s uintptr, level, name int, b []byte) (int, error) { - l := uint32(len(b)) - _, _, errno := syscall_syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0) - return int(l), errnoErr(errno) -} - -func setsockopt(s uintptr, level, name int, b []byte) error { - _, _, errno := syscall_syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0) - return errnoErr(errno) -} - -func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { - var h msghdr - vs := make([]iovec, len(buffers)) - var sa []byte - if network != "tcp" { - sa = make([]byte, sizeofSockaddrInet6) - } - h.pack(vs, buffers, oob, sa) - sn, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags)) - n = int(sn) - oobn = h.controllen() - recvflags = h.flags() - err = errnoErr(errno) - if network != "tcp" { - var err2 error - from, err2 = parseInetAddr(sa, network) - if err2 != nil && err == nil { - err = err2 - } - } - return -} - -func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { - var h msghdr - vs := make([]iovec, len(buffers)) - var sa []byte - if to != nil { - var a [sizeofSockaddrInet6]byte - n := marshalInetAddr(to, a[:]) - sa = a[:n] - } - h.pack(vs, buffers, oob, sa) - n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags)) - return int(n), errnoErr(errno) -} diff --git a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s deleted file mode 100644 index 60d5839c2..000000000 --- a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.s +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -#include "textflag.h" - -TEXT ·syscall_syscall(SB),NOSPLIT,$0 - JMP syscall·_syscall(SB) - -TEXT ·syscall_syscall6(SB),NOSPLIT,$0 - JMP syscall·_syscall6(SB) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go deleted file mode 100644 index 45bab004c..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go +++ /dev/null @@ -1,39 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_aix.go - -// Added for go1.11 compatibility -//go:build aix - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go deleted file mode 100644 index 98dcfe412..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_darwin.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen int32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go deleted file mode 100644 index 98dcfe412..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_darwin.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen int32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go deleted file mode 100644 index 636d129ae..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_dragonfly.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen int32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go deleted file mode 100644 index 87707fed0..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go deleted file mode 100644 index 7db778112..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen int32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go deleted file mode 100644 index 87707fed0..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go deleted file mode 100644 index 7db778112..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen int32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go deleted file mode 100644 index 965c0b28b..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go deleted file mode 100644 index 4c19269be..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_386.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go deleted file mode 100644 index 3dcd5c8ed..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_1 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go deleted file mode 100644 index 4c19269be..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go deleted file mode 100644 index 3dcd5c8ed..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_1 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go deleted file mode 100644 index b6fc15a1a..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_loong64.go +++ /dev/null @@ -1,39 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -//go:build loong64 - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_0 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go deleted file mode 100644 index 4c19269be..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go deleted file mode 100644 index 3dcd5c8ed..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_1 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go deleted file mode 100644 index 3dcd5c8ed..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_1 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go deleted file mode 100644 index 4c19269be..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go deleted file mode 100644 index 4c19269be..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go deleted file mode 100644 index 3dcd5c8ed..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_1 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go deleted file mode 100644 index 3dcd5c8ed..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_1 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go deleted file mode 100644 index e67fc3cba..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go +++ /dev/null @@ -1,39 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -//go:build riscv64 - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_0 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go b/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go deleted file mode 100644 index 3dcd5c8ed..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint64 - Control *byte - Controllen uint64 - Flags int32 - Pad_cgo_1 [4]byte -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint64 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x38 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go deleted file mode 100644 index f95572dc0..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_netbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go deleted file mode 100644 index a92fd60e4..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_netbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen int32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go deleted file mode 100644 index f95572dc0..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go +++ /dev/null @@ -1,35 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_netbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go deleted file mode 100644 index a92fd60e4..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_netbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen int32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type mmsghdr struct { - Hdr msghdr - Len uint32 - Pad_cgo_0 [4]byte -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go deleted file mode 100644 index e792ec211..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_openbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go deleted file mode 100644 index b68ff2d57..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_openbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go deleted file mode 100644 index e792ec211..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_openbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go deleted file mode 100644 index b68ff2d57..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_openbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen uint32 - Pad_cgo_1 [4]byte - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go deleted file mode 100644 index 3c9576e2d..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_mips64.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_openbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_ppc64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_ppc64.go deleted file mode 100644 index cebde7634..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_ppc64.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_openbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_riscv64.go b/vendor/golang.org/x/net/internal/socket/zsys_openbsd_riscv64.go deleted file mode 100644 index cebde7634..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_openbsd_riscv64.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_openbsd.go - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen uint32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go b/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go deleted file mode 100644 index 359cfec40..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go +++ /dev/null @@ -1,32 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_solaris.go - -package socket - -type iovec struct { - Base *int8 - Len uint64 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Pad_cgo_0 [4]byte - Iov *iovec - Iovlen int32 - Pad_cgo_1 [4]byte - Accrights *int8 - Accrightslen int32 - Pad_cgo_2 [4]byte -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x10 - sizeofMsghdr = 0x30 -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go deleted file mode 100644 index 49b62c856..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_zos_s390x.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package socket - -type iovec struct { - Base *byte - Len uint64 -} - -type msghdr struct { - Name *byte - Iov *iovec - Control *byte - Flags int32 - Namelen uint32 - Iovlen int32 - Controllen uint32 -} - -type cmsghdr struct { - Len int32 - Level int32 - Type int32 -} - -const sizeofCmsghdr = 12 diff --git a/vendor/golang.org/x/net/ipv4/batch.go b/vendor/golang.org/x/net/ipv4/batch.go deleted file mode 100644 index 1a3a4fc0c..000000000 --- a/vendor/golang.org/x/net/ipv4/batch.go +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ipv4 - -import ( - "net" - "runtime" - - "golang.org/x/net/internal/socket" -) - -// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of -// PacketConn are not implemented. - -// BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of -// RawConn are not implemented. - -// A Message represents an IO message. -// -// type Message struct { -// Buffers [][]byte -// OOB []byte -// Addr net.Addr -// N int -// NN int -// Flags int -// } -// -// The Buffers fields represents a list of contiguous buffers, which -// can be used for vectored IO, for example, putting a header and a -// payload in each slice. -// When writing, the Buffers field must contain at least one byte to -// write. -// When reading, the Buffers field will always contain a byte to read. -// -// The OOB field contains protocol-specific control or miscellaneous -// ancillary data known as out-of-band data. -// It can be nil when not required. -// -// The Addr field specifies a destination address when writing. -// It can be nil when the underlying protocol of the endpoint uses -// connection-oriented communication. -// After a successful read, it may contain the source address on the -// received packet. -// -// The N field indicates the number of bytes read or written from/to -// Buffers. -// -// The NN field indicates the number of bytes read or written from/to -// OOB. -// -// The Flags field contains protocol-specific information on the -// received message. -type Message = socket.Message - -// ReadBatch reads a batch of messages. -// -// The provided flags is a set of platform-dependent flags, such as -// syscall.MSG_PEEK. -// -// On a successful read it returns the number of messages received, up -// to len(ms). -// -// On Linux, a batch read will be optimized. -// On other platforms, this method will read only a single message. -// -// Unlike the ReadFrom method, it doesn't strip the IPv4 header -// followed by option headers from the received IPv4 datagram when the -// underlying transport is net.IPConn. Each Buffers field of Message -// must be large enough to accommodate an IPv4 header and option -// headers. -func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) { - if !c.ok() { - return 0, errInvalidConn - } - switch runtime.GOOS { - case "linux": - n, err := c.RecvMsgs([]socket.Message(ms), flags) - if err != nil { - err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - return n, err - default: - n := 1 - err := c.RecvMsg(&ms[0], flags) - if err != nil { - n = 0 - err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - if compatFreeBSD32 && ms[0].NN > 0 { - adjustFreeBSD32(&ms[0]) - } - return n, err - } -} - -// WriteBatch writes a batch of messages. -// -// The provided flags is a set of platform-dependent flags, such as -// syscall.MSG_DONTROUTE. -// -// It returns the number of messages written on a successful write. -// -// On Linux, a batch write will be optimized. -// On other platforms, this method will write only a single message. -func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) { - if !c.ok() { - return 0, errInvalidConn - } - switch runtime.GOOS { - case "linux": - n, err := c.SendMsgs([]socket.Message(ms), flags) - if err != nil { - err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - return n, err - default: - n := 1 - err := c.SendMsg(&ms[0], flags) - if err != nil { - n = 0 - err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - return n, err - } -} - -// ReadBatch reads a batch of messages. -// -// The provided flags is a set of platform-dependent flags, such as -// syscall.MSG_PEEK. -// -// On a successful read it returns the number of messages received, up -// to len(ms). -// -// On Linux, a batch read will be optimized. -// On other platforms, this method will read only a single message. -func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) { - if !c.ok() { - return 0, errInvalidConn - } - switch runtime.GOOS { - case "linux": - n, err := c.RecvMsgs([]socket.Message(ms), flags) - if err != nil { - err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - return n, err - default: - n := 1 - err := c.RecvMsg(&ms[0], flags) - if err != nil { - n = 0 - err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - if compatFreeBSD32 && ms[0].NN > 0 { - adjustFreeBSD32(&ms[0]) - } - return n, err - } -} - -// WriteBatch writes a batch of messages. -// -// The provided flags is a set of platform-dependent flags, such as -// syscall.MSG_DONTROUTE. -// -// It returns the number of messages written on a successful write. -// -// On Linux, a batch write will be optimized. -// On other platforms, this method will write only a single message. -func (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) { - if !c.ok() { - return 0, errInvalidConn - } - switch runtime.GOOS { - case "linux": - n, err := c.SendMsgs([]socket.Message(ms), flags) - if err != nil { - err = &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - return n, err - default: - n := 1 - err := c.SendMsg(&ms[0], flags) - if err != nil { - n = 0 - err = &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - return n, err - } -} diff --git a/vendor/golang.org/x/net/ipv4/control.go b/vendor/golang.org/x/net/ipv4/control.go deleted file mode 100644 index a2b02ca95..000000000 --- a/vendor/golang.org/x/net/ipv4/control.go +++ /dev/null @@ -1,144 +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 ( - "fmt" - "net" - "sync" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" -) - -type rawOpt struct { - sync.RWMutex - cflags ControlFlags -} - -func (c *rawOpt) set(f ControlFlags) { c.cflags |= f } -func (c *rawOpt) clear(f ControlFlags) { c.cflags &^= f } -func (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 } - -type ControlFlags uint - -const ( - FlagTTL ControlFlags = 1 << iota // pass the TTL on the received packet - FlagSrc // pass the source address on the received packet - FlagDst // pass the destination address on the received packet - FlagInterface // pass the interface index on the received packet -) - -// A ControlMessage represents per packet basis IP-level socket options. -type ControlMessage struct { - // Receiving socket options: SetControlMessage allows to - // receive the options from the protocol stack using ReadFrom - // method of PacketConn or RawConn. - // - // Specifying socket options: ControlMessage for WriteTo - // method of PacketConn or RawConn allows to send the options - // to the protocol stack. - // - TTL int // time-to-live, receiving only - Src net.IP // source address, specifying only - Dst net.IP // destination address, receiving only - IfIndex int // interface index, must be 1 <= value when specifying -} - -func (cm *ControlMessage) String() string { - if cm == nil { - return "" - } - 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 - ctlSrc // header field - ctlDst // header field - ctlInterface // inbound or outbound interface - ctlPacketInfo // inbound or outbound packet path - ctlMax -) - -// A ctlOpt represents a binding for ancillary data socket option. -type ctlOpt struct { - name int // option name, must be equal or greater than 1 - length int // option length - marshal func([]byte, *ControlMessage) []byte - parse func(*ControlMessage, []byte) -} diff --git a/vendor/golang.org/x/net/ipv4/control_bsd.go b/vendor/golang.org/x/net/ipv4/control_bsd.go deleted file mode 100644 index c88da8cbe..000000000 --- a/vendor/golang.org/x/net/ipv4/control_bsd.go +++ /dev/null @@ -1,43 +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. - -//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd - -package ipv4 - -import ( - "net" - "syscall" - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -func marshalDst(b []byte, cm *ControlMessage) []byte { - m := socket.ControlMessage(b) - m.MarshalHeader(iana.ProtocolIP, unix.IP_RECVDSTADDR, net.IPv4len) - return m.Next(net.IPv4len) -} - -func parseDst(cm *ControlMessage, b []byte) { - 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 := socket.ControlMessage(b) - m.MarshalHeader(iana.ProtocolIP, sockoptReceiveInterface, syscall.SizeofSockaddrDatalink) - return m.Next(syscall.SizeofSockaddrDatalink) -} - -func parseInterface(cm *ControlMessage, b []byte) { - var sadl syscall.SockaddrDatalink - copy((*[unsafe.Sizeof(sadl)]byte)(unsafe.Pointer(&sadl))[:], b) - cm.IfIndex = int(sadl.Index) -} diff --git a/vendor/golang.org/x/net/ipv4/control_pktinfo.go b/vendor/golang.org/x/net/ipv4/control_pktinfo.go deleted file mode 100644 index 14ae2dae4..000000000 --- a/vendor/golang.org/x/net/ipv4/control_pktinfo.go +++ /dev/null @@ -1,41 +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. - -//go:build darwin || linux || solaris - -package ipv4 - -import ( - "net" - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -func marshalPacketInfo(b []byte, cm *ControlMessage) []byte { - m := socket.ControlMessage(b) - m.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo) - if cm != nil { - pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0])) - if ip := cm.Src.To4(); ip != nil { - copy(pi.Spec_dst[:], ip) - } - if cm.IfIndex > 0 { - pi.setIfindex(cm.IfIndex) - } - } - return m.Next(sizeofInetPktinfo) -} - -func parsePacketInfo(cm *ControlMessage, b []byte) { - pi := (*inetPktinfo)(unsafe.Pointer(&b[0])) - cm.IfIndex = int(pi.Ifindex) - if len(cm.Dst) < net.IPv4len { - cm.Dst = make(net.IP, net.IPv4len) - } - copy(cm.Dst, pi.Addr[:]) -} diff --git a/vendor/golang.org/x/net/ipv4/control_stub.go b/vendor/golang.org/x/net/ipv4/control_stub.go deleted file mode 100644 index 3ba661160..000000000 --- a/vendor/golang.org/x/net/ipv4/control_stub.go +++ /dev/null @@ -1,13 +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. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos - -package ipv4 - -import "golang.org/x/net/internal/socket" - -func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { - return errNotImplemented -} diff --git a/vendor/golang.org/x/net/ipv4/control_unix.go b/vendor/golang.org/x/net/ipv4/control_unix.go deleted file mode 100644 index 2e765548f..000000000 --- a/vendor/golang.org/x/net/ipv4/control_unix.go +++ /dev/null @@ -1,75 +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. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris - -package ipv4 - -import ( - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { - opt.Lock() - defer opt.Unlock() - if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 { - if err := so.SetInt(c, boolint(on)); err != nil { - return err - } - if on { - opt.set(FlagTTL) - } else { - opt.clear(FlagTTL) - } - } - if so, ok := sockOpts[ssoPacketInfo]; ok { - if cf&(FlagSrc|FlagDst|FlagInterface) != 0 { - if err := so.SetInt(c, boolint(on)); err != nil { - return err - } - if on { - opt.set(cf & (FlagSrc | FlagDst | FlagInterface)) - } else { - opt.clear(cf & (FlagSrc | FlagDst | FlagInterface)) - } - } - } else { - if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 { - if err := so.SetInt(c, boolint(on)); err != nil { - return err - } - if on { - opt.set(FlagDst) - } else { - opt.clear(FlagDst) - } - } - if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 { - if err := so.SetInt(c, boolint(on)); err != nil { - return err - } - if on { - opt.set(FlagInterface) - } else { - opt.clear(FlagInterface) - } - } - } - return nil -} - -func marshalTTL(b []byte, cm *ControlMessage) []byte { - m := socket.ControlMessage(b) - m.MarshalHeader(iana.ProtocolIP, unix.IP_RECVTTL, 1) - return m.Next(1) -} - -func parseTTL(cm *ControlMessage, b []byte) { - cm.TTL = int(*(*byte)(unsafe.Pointer(&b[:1][0]))) -} diff --git a/vendor/golang.org/x/net/ipv4/control_windows.go b/vendor/golang.org/x/net/ipv4/control_windows.go deleted file mode 100644 index 82c630642..000000000 --- a/vendor/golang.org/x/net/ipv4/control_windows.go +++ /dev/null @@ -1,12 +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 "golang.org/x/net/internal/socket" - -func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { - // TODO(mikio): implement this - return errNotImplemented -} diff --git a/vendor/golang.org/x/net/ipv4/control_zos.go b/vendor/golang.org/x/net/ipv4/control_zos.go deleted file mode 100644 index de11c42e5..000000000 --- a/vendor/golang.org/x/net/ipv4/control_zos.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ipv4 - -import ( - "net" - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -func marshalPacketInfo(b []byte, cm *ControlMessage) []byte { - m := socket.ControlMessage(b) - m.MarshalHeader(iana.ProtocolIP, unix.IP_PKTINFO, sizeofInetPktinfo) - if cm != nil { - pi := (*inetPktinfo)(unsafe.Pointer(&m.Data(sizeofInetPktinfo)[0])) - if ip := cm.Src.To4(); ip != nil { - copy(pi.Addr[:], ip) - } - if cm.IfIndex > 0 { - pi.setIfindex(cm.IfIndex) - } - } - return m.Next(sizeofInetPktinfo) -} - -func parsePacketInfo(cm *ControlMessage, b []byte) { - pi := (*inetPktinfo)(unsafe.Pointer(&b[0])) - cm.IfIndex = int(pi.Ifindex) - if len(cm.Dst) < net.IPv4len { - cm.Dst = make(net.IP, net.IPv4len) - } - copy(cm.Dst, pi.Addr[:]) -} - -func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error { - opt.Lock() - defer opt.Unlock() - if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 { - if err := so.SetInt(c, boolint(on)); err != nil { - return err - } - if on { - opt.set(FlagTTL) - } else { - opt.clear(FlagTTL) - } - } - if so, ok := sockOpts[ssoPacketInfo]; ok { - if cf&(FlagSrc|FlagDst|FlagInterface) != 0 { - if err := so.SetInt(c, boolint(on)); err != nil { - return err - } - if on { - opt.set(cf & (FlagSrc | FlagDst | FlagInterface)) - } else { - opt.clear(cf & (FlagSrc | FlagDst | FlagInterface)) - } - } - } else { - if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 { - if err := so.SetInt(c, boolint(on)); err != nil { - return err - } - if on { - opt.set(FlagDst) - } else { - opt.clear(FlagDst) - } - } - if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 { - if err := so.SetInt(c, boolint(on)); err != nil { - return err - } - if on { - opt.set(FlagInterface) - } else { - opt.clear(FlagInterface) - } - } - } - return nil -} diff --git a/vendor/golang.org/x/net/ipv4/dgramopt.go b/vendor/golang.org/x/net/ipv4/dgramopt.go deleted file mode 100644 index c191c22ab..000000000 --- a/vendor/golang.org/x/net/ipv4/dgramopt.go +++ /dev/null @@ -1,264 +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" - - "golang.org/x/net/bpf" -) - -// MulticastTTL returns the time-to-live field value for outgoing -// multicast packets. -func (c *dgramOpt) MulticastTTL() (int, error) { - if !c.ok() { - return 0, errInvalidConn - } - so, ok := sockOpts[ssoMulticastTTL] - if !ok { - return 0, errNotImplemented - } - return so.GetInt(c.Conn) -} - -// SetMulticastTTL sets the time-to-live field value for future -// outgoing multicast packets. -func (c *dgramOpt) SetMulticastTTL(ttl int) error { - if !c.ok() { - return errInvalidConn - } - so, ok := sockOpts[ssoMulticastTTL] - if !ok { - return errNotImplemented - } - return so.SetInt(c.Conn, ttl) -} - -// MulticastInterface returns the default interface for multicast -// packet transmissions. -func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { - if !c.ok() { - return nil, errInvalidConn - } - so, ok := sockOpts[ssoMulticastInterface] - if !ok { - return nil, errNotImplemented - } - return so.getMulticastInterface(c.Conn) -} - -// SetMulticastInterface sets the default interface for future -// multicast packet transmissions. -func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { - if !c.ok() { - return errInvalidConn - } - so, ok := sockOpts[ssoMulticastInterface] - if !ok { - return errNotImplemented - } - return so.setMulticastInterface(c.Conn, 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, errInvalidConn - } - so, ok := sockOpts[ssoMulticastLoopback] - if !ok { - return false, errNotImplemented - } - on, err := so.GetInt(c.Conn) - 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 errInvalidConn - } - so, ok := sockOpts[ssoMulticastLoopback] - if !ok { - return errNotImplemented - } - return so.SetInt(c.Conn, 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 errInvalidConn - } - so, ok := sockOpts[ssoJoinGroup] - if !ok { - return errNotImplemented - } - grp := netAddrToIP4(group) - if grp == nil { - return errMissingAddress - } - return so.setGroup(c.Conn, 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 errInvalidConn - } - so, ok := sockOpts[ssoLeaveGroup] - if !ok { - return errNotImplemented - } - grp := netAddrToIP4(group) - if grp == nil { - return errMissingAddress - } - return so.setGroup(c.Conn, 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 errInvalidConn - } - so, ok := sockOpts[ssoJoinSourceGroup] - if !ok { - return errNotImplemented - } - grp := netAddrToIP4(group) - if grp == nil { - return errMissingAddress - } - src := netAddrToIP4(source) - if src == nil { - return errMissingAddress - } - return so.setSourceGroup(c.Conn, 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 errInvalidConn - } - so, ok := sockOpts[ssoLeaveSourceGroup] - if !ok { - return errNotImplemented - } - grp := netAddrToIP4(group) - if grp == nil { - return errMissingAddress - } - src := netAddrToIP4(source) - if src == nil { - return errMissingAddress - } - return so.setSourceGroup(c.Conn, 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 errInvalidConn - } - so, ok := sockOpts[ssoBlockSourceGroup] - if !ok { - return errNotImplemented - } - grp := netAddrToIP4(group) - if grp == nil { - return errMissingAddress - } - src := netAddrToIP4(source) - if src == nil { - return errMissingAddress - } - return so.setSourceGroup(c.Conn, 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 errInvalidConn - } - so, ok := sockOpts[ssoUnblockSourceGroup] - if !ok { - return errNotImplemented - } - grp := netAddrToIP4(group) - if grp == nil { - return errMissingAddress - } - src := netAddrToIP4(source) - if src == nil { - return errMissingAddress - } - return so.setSourceGroup(c.Conn, ifi, grp, src) -} - -// ICMPFilter returns an ICMP filter. -// Currently only Linux supports this. -func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { - if !c.ok() { - return nil, errInvalidConn - } - so, ok := sockOpts[ssoICMPFilter] - if !ok { - return nil, errNotImplemented - } - return so.getICMPFilter(c.Conn) -} - -// SetICMPFilter deploys the ICMP filter. -// Currently only Linux supports this. -func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { - if !c.ok() { - return errInvalidConn - } - so, ok := sockOpts[ssoICMPFilter] - if !ok { - return errNotImplemented - } - return so.setICMPFilter(c.Conn, f) -} - -// SetBPF attaches a BPF program to the connection. -// -// Only supported on Linux. -func (c *dgramOpt) SetBPF(filter []bpf.RawInstruction) error { - if !c.ok() { - return errInvalidConn - } - so, ok := sockOpts[ssoAttachFilter] - if !ok { - return errNotImplemented - } - return so.setBPF(c.Conn, filter) -} diff --git a/vendor/golang.org/x/net/ipv4/doc.go b/vendor/golang.org/x/net/ipv4/doc.go deleted file mode 100644 index 6fbdc52b9..000000000 --- a/vendor/golang.org/x/net/ipv4/doc.go +++ /dev/null @@ -1,240 +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 implements IP-level socket options for the Internet -// Protocol version 4. -// -// The package provides IP-level socket options that allow -// manipulation of IPv4 facilities. -// -// The IPv4 protocol and basic host requirements for IPv4 are defined -// in RFC 791 and RFC 1122. -// Host extensions for multicasting and socket interface extensions -// for multicast source filters are defined in RFC 1112 and RFC 3678. -// IGMPv1, IGMPv2 and IGMPv3 are defined in RFC 1112, RFC 2236 and RFC -// 3376. -// Source-specific multicast is defined in RFC 4607. -// -// # Unicasting -// -// 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 -// a data flow of multiple packets needs to indicate the flow is -// 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 { -// // error handling -// } -// defer ln.Close() -// for { -// c, err := ln.Accept() -// if err != nil { -// // error handling -// } -// go func(c net.Conn) { -// defer c.Close() -// -// The outgoing packets will be labeled DiffServ assured forwarding -// class 1 low drop precedence, known as AF11 packets. -// -// if err := ipv4.NewConn(c).SetTOS(0x28); err != nil { -// // error handling -// } -// if _, err := c.Write(data); err != nil { -// // error handling -// } -// }(c) -// } -// -// # Multicasting -// -// 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 -// you begin multicasting, at a minimum joining network interfaces and -// multicast groups. -// -// en0, err := net.InterfaceByName("en0") -// if err != nil { -// // error handling -// } -// en1, err := net.InterfaceByIndex(911) -// if err != nil { -// // error handling -// } -// group := net.IPv4(224, 0, 0, 250) -// -// First, an application listens to an appropriate address with an -// appropriate service port. -// -// c, err := net.ListenPacket("udp4", "0.0.0.0:1024") -// if err != nil { -// // error handling -// } -// defer c.Close() -// -// Second, the application joins multicast groups, starts listening to -// 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. -// -// p := ipv4.NewPacketConn(c) -// if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil { -// // error handling -// } -// if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil { -// // error handling -// } -// -// The application might set per packet control message transmissions -// between the protocol stack within the kernel. When the application -// needs a destination address on an incoming packet, -// SetControlMessage of PacketConn is used to enable control message -// transmissions. -// -// if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil { -// // error handling -// } -// -// The application could identify whether the received packets are -// of interest by using the control message that contains the -// destination address of the received packet. -// -// b := make([]byte, 1500) -// for { -// n, cm, src, err := p.ReadFrom(b) -// if err != nil { -// // error handling -// } -// if cm.Dst.IsMulticast() { -// if cm.Dst.Equal(group) { -// // joined group, do something -// } else { -// // unknown group, discard -// continue -// } -// } -// -// The application can also send both unicast and multicast packets. -// -// p.SetTOS(0x0) -// p.SetTTL(16) -// if _, err := p.WriteTo(data, nil, src); err != nil { -// // error handling -// } -// dst := &net.UDPAddr{IP: group, Port: 1024} -// for _, ifi := range []*net.Interface{en0, en1} { -// if err := p.SetMulticastInterface(ifi); err != nil { -// // error handling -// } -// p.SetMulticastTTL(2) -// if _, err := p.WriteTo(data, nil, dst); 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 -// join two different groups across over two different network -// interfaces by using: -// -// c, err := net.ListenPacket("udp4", "0.0.0.0:1024") -// if err != nil { -// // error handling -// } -// defer c.Close() -// p := ipv4.NewPacketConn(c) -// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil { -// // error handling -// } -// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}); err != nil { -// // error handling -// } -// if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}); err != nil { -// // error handling -// } -// -// It is possible for multiple UDP listeners that listen on the same -// 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. -// -// c1, err := net.ListenPacket("udp4", "224.0.0.0:1024") -// if err != nil { -// // error handling -// } -// defer c1.Close() -// c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") -// if err != nil { -// // error handling -// } -// defer c2.Close() -// p1 := ipv4.NewPacketConn(c1) -// if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil { -// // error handling -// } -// p2 := ipv4.NewPacketConn(c2) -// if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil { -// // error handling -// } -// -// Also it is possible for the application to leave or rejoin a -// multicast group on the network interface. -// -// if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil { -// // error handling -// } -// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)}); err != nil { -// // error handling -// } -// -// # Source-specific multicasting -// -// An application that uses PacketConn or RawConn on IGMPv3 supported -// platform is able to join source-specific multicast groups. -// The application may use JoinSourceSpecificGroup and -// LeaveSourceSpecificGroup for the operation known as "include" mode, -// -// ssmgroup := net.UDPAddr{IP: net.IPv4(232, 7, 8, 9)} -// ssmsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)} -// if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil { -// // error handling -// } -// if err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil { -// // error handling -// } -// -// or JoinGroup, ExcludeSourceSpecificGroup, -// IncludeSourceSpecificGroup and LeaveGroup for the operation known -// as "exclude" mode. -// -// exclsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 254)} -// if err := p.JoinGroup(en0, &ssmgroup); err != nil { -// // error handling -// } -// if err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil { -// // error handling -// } -// if err := p.LeaveGroup(en0, &ssmgroup); err != nil { -// // error handling -// } -// -// Note that it depends on each platform implementation what happens -// when an application which runs on IGMPv3 unsupported platform uses -// JoinSourceSpecificGroup and LeaveSourceSpecificGroup. -// In general the platform tries to fall back to conversations using -// IGMPv1 or IGMPv2 and starts to listen to multicast traffic. -// 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 JS, NaCl and Plan 9. diff --git a/vendor/golang.org/x/net/ipv4/endpoint.go b/vendor/golang.org/x/net/ipv4/endpoint.go deleted file mode 100644 index 4a6d7a85e..000000000 --- a/vendor/golang.org/x/net/ipv4/endpoint.go +++ /dev/null @@ -1,186 +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" - "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. -type Conn struct { - genericOpt -} - -type genericOpt struct { - *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: 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 -// network I/O methods specific to the IPv4 and higher layer protocols -// such as UDP. -type PacketConn struct { - genericOpt - dgramOpt - payloadHandler -} - -type dgramOpt struct { - *socket.Conn -} - -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 errInvalidConn - } - return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on) -} - -// SetDeadline sets the read and write deadlines associated with the -// endpoint. -func (c *PacketConn) SetDeadline(t time.Time) error { - if !c.payloadHandler.ok() { - return errInvalidConn - } - return c.payloadHandler.PacketConn.SetDeadline(t) -} - -// SetReadDeadline sets the read deadline associated with the -// endpoint. -func (c *PacketConn) SetReadDeadline(t time.Time) error { - if !c.payloadHandler.ok() { - return errInvalidConn - } - return c.payloadHandler.PacketConn.SetReadDeadline(t) -} - -// SetWriteDeadline sets the write deadline associated with the -// endpoint. -func (c *PacketConn) SetWriteDeadline(t time.Time) error { - if !c.payloadHandler.ok() { - return errInvalidConn - } - return c.payloadHandler.PacketConn.SetWriteDeadline(t) -} - -// Close closes the endpoint. -func (c *PacketConn) Close() error { - if !c.payloadHandler.ok() { - return errInvalidConn - } - return c.payloadHandler.PacketConn.Close() -} - -// 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: 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 -// 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 { - genericOpt - dgramOpt - packetHandler -} - -// SetControlMessage sets the per packet IP-level socket options. -func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error { - if !c.packetHandler.ok() { - return errInvalidConn - } - return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on) -} - -// SetDeadline sets the read and write deadlines associated with the -// endpoint. -func (c *RawConn) SetDeadline(t time.Time) error { - if !c.packetHandler.ok() { - return errInvalidConn - } - return c.packetHandler.IPConn.SetDeadline(t) -} - -// SetReadDeadline sets the read deadline associated with the -// endpoint. -func (c *RawConn) SetReadDeadline(t time.Time) error { - if !c.packetHandler.ok() { - return errInvalidConn - } - return c.packetHandler.IPConn.SetReadDeadline(t) -} - -// SetWriteDeadline sets the write deadline associated with the -// endpoint. -func (c *RawConn) SetWriteDeadline(t time.Time) error { - if !c.packetHandler.ok() { - return errInvalidConn - } - return c.packetHandler.IPConn.SetWriteDeadline(t) -} - -// Close closes the endpoint. -func (c *RawConn) Close() error { - if !c.packetHandler.ok() { - return errInvalidConn - } - return c.packetHandler.IPConn.Close() -} - -// NewRawConn returns a new RawConn using c as its underlying -// transport. -func NewRawConn(c net.PacketConn) (*RawConn, error) { - cc, err := socket.NewConn(c.(net.Conn)) - if err != nil { - return nil, err - } - 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, errNotImplemented - } - if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil { - return nil, err - } - return r, nil -} diff --git a/vendor/golang.org/x/net/ipv4/genericopt.go b/vendor/golang.org/x/net/ipv4/genericopt.go deleted file mode 100644 index 51c12371e..000000000 --- a/vendor/golang.org/x/net/ipv4/genericopt.go +++ /dev/null @@ -1,55 +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 - -// TOS returns the type-of-service field value for outgoing packets. -func (c *genericOpt) TOS() (int, error) { - if !c.ok() { - return 0, errInvalidConn - } - so, ok := sockOpts[ssoTOS] - if !ok { - return 0, errNotImplemented - } - return so.GetInt(c.Conn) -} - -// SetTOS sets the type-of-service field value for future outgoing -// packets. -func (c *genericOpt) SetTOS(tos int) error { - if !c.ok() { - return errInvalidConn - } - so, ok := sockOpts[ssoTOS] - if !ok { - return errNotImplemented - } - return so.SetInt(c.Conn, tos) -} - -// TTL returns the time-to-live field value for outgoing packets. -func (c *genericOpt) TTL() (int, error) { - if !c.ok() { - return 0, errInvalidConn - } - so, ok := sockOpts[ssoTTL] - if !ok { - return 0, errNotImplemented - } - return so.GetInt(c.Conn) -} - -// SetTTL sets the time-to-live field value for future outgoing -// packets. -func (c *genericOpt) SetTTL(ttl int) error { - if !c.ok() { - return errInvalidConn - } - so, ok := sockOpts[ssoTTL] - if !ok { - return errNotImplemented - } - return so.SetInt(c.Conn, ttl) -} diff --git a/vendor/golang.org/x/net/ipv4/header.go b/vendor/golang.org/x/net/ipv4/header.go deleted file mode 100644 index a00a3eaff..000000000 --- a/vendor/golang.org/x/net/ipv4/header.go +++ /dev/null @@ -1,172 +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 ( - "encoding/binary" - "fmt" - "net" - "runtime" - - "golang.org/x/net/internal/socket" -) - -const ( - Version = 4 // protocol version - HeaderLen = 20 // header length without extension headers -) - -type HeaderFlags int - -const ( - MoreFragments HeaderFlags = 1 << iota // more fragments flag - DontFragment // don't fragment flag -) - -// A Header represents an IPv4 header. -type Header struct { - Version int // protocol version - Len int // header length - TOS int // type-of-service - TotalLen int // packet total length - ID int // identification - Flags HeaderFlags // flags - FragOff int // fragment offset - TTL int // time-to-live - Protocol int // next protocol - Checksum int // checksum - Src net.IP // source address - Dst net.IP // destination address - Options []byte // options, extension headers -} - -func (h *Header) String() string { - if h == nil { - return "" - } - 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 h. -// -// The returned slice is in the format used by a raw IP socket on the -// local system. -// This may differ from the wire format, depending on the system. -func (h *Header) Marshal() ([]byte, error) { - if h == nil { - return nil, errNilHeader - } - if h.Len < HeaderLen { - return nil, errHeaderTooShort - } - hdrlen := HeaderLen + len(h.Options) - b := make([]byte, hdrlen) - b[0] = byte(Version<<4 | (hdrlen >> 2 & 0x0f)) - b[1] = byte(h.TOS) - flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13) - switch runtime.GOOS { - case "darwin", "ios", "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)) - } - binary.BigEndian.PutUint16(b[4:6], uint16(h.ID)) - b[8] = byte(h.TTL) - b[9] = byte(h.Protocol) - binary.BigEndian.PutUint16(b[10:12], uint16(h.Checksum)) - if ip := h.Src.To4(); ip != nil { - copy(b[12:16], ip[:net.IPv4len]) - } - if ip := h.Dst.To4(); ip != nil { - copy(b[16:20], ip[:net.IPv4len]) - } else { - return nil, errMissingAddress - } - if len(h.Options) > 0 { - copy(b[HeaderLen:], h.Options) - } - return b, nil -} - -// Parse parses b as an IPv4 header and stores the result in h. -// -// The provided b must be in the format used by a raw IP socket on the -// local system. -// This may differ from the wire format, depending on the system. -func (h *Header) Parse(b []byte) error { - if h == nil || b == nil { - return errNilHeader - } - if len(b) < HeaderLen { - return errHeaderTooShort - } - hdrlen := int(b[0]&0x0f) << 2 - if len(b) < hdrlen { - return errExtHeaderTooShort - } - 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", "ios", "dragonfly", "netbsd": - h.TotalLen = int(socket.NativeEndian.Uint16(b[2:4])) + hdrlen - h.FragOff = int(socket.NativeEndian.Uint16(b[6:8])) - case "freebsd": - 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])) - } - 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 - 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. -// -// The provided b must be in the format used by a raw IP socket on the -// local system. -// This may differ from the wire format, depending on the system. -func ParseHeader(b []byte) (*Header, error) { - h := new(Header) - if err := h.Parse(b); err != nil { - return nil, err - } - return h, nil -} diff --git a/vendor/golang.org/x/net/ipv4/helper.go b/vendor/golang.org/x/net/ipv4/helper.go deleted file mode 100644 index e845a7376..000000000 --- a/vendor/golang.org/x/net/ipv4/helper.go +++ /dev/null @@ -1,77 +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 ( - "errors" - "net" - "runtime" - - "golang.org/x/net/internal/socket" -) - -var ( - errInvalidConn = errors.New("invalid connection") - errMissingAddress = errors.New("missing address") - errNilHeader = errors.New("nil header") - errHeaderTooShort = errors.New("header too short") - errExtHeaderTooShort = errors.New("extension header too short") - errInvalidConnType = errors.New("invalid conn type") - errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH) - - // See https://www.freebsd.org/doc/en/books/porters-handbook/versions.html. - freebsdVersion uint32 - compatFreeBSD32 bool // 386 emulation on amd64 -) - -// See golang.org/issue/30899. -func adjustFreeBSD32(m *socket.Message) { - // FreeBSD 12.0-RELEASE is affected by https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236737 - if 1200086 <= freebsdVersion && freebsdVersion < 1201000 { - l := (m.NN + 4 - 1) &^ (4 - 1) - if m.NN < l && l <= len(m.OOB) { - m.NN = l - } - } -} - -func boolint(b bool) int { - if b { - return 1 - } - return 0 -} - -func netAddrToIP4(a net.Addr) net.IP { - switch v := a.(type) { - case *net.UDPAddr: - if ip := v.IP.To4(); ip != nil { - return ip - } - case *net.IPAddr: - if ip := v.IP.To4(); ip != nil { - return 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/iana.go b/vendor/golang.org/x/net/ipv4/iana.go deleted file mode 100644 index 4375b4099..000000000 --- a/vendor/golang.org/x/net/ipv4/iana.go +++ /dev/null @@ -1,38 +0,0 @@ -// go generate gen.go -// Code generated by the command above; DO NOT EDIT. - -package ipv4 - -// Internet Control Message Protocol (ICMP) Parameters, Updated: 2018-02-26 -const ( - ICMPTypeEchoReply ICMPType = 0 // Echo Reply - ICMPTypeDestinationUnreachable ICMPType = 3 // Destination Unreachable - ICMPTypeRedirect ICMPType = 5 // Redirect - ICMPTypeEcho ICMPType = 8 // Echo - ICMPTypeRouterAdvertisement ICMPType = 9 // Router Advertisement - ICMPTypeRouterSolicitation ICMPType = 10 // Router Solicitation - ICMPTypeTimeExceeded ICMPType = 11 // Time Exceeded - ICMPTypeParameterProblem ICMPType = 12 // Parameter Problem - ICMPTypeTimestamp ICMPType = 13 // Timestamp - ICMPTypeTimestampReply ICMPType = 14 // Timestamp Reply - ICMPTypePhoturis ICMPType = 40 // Photuris - ICMPTypeExtendedEchoRequest ICMPType = 42 // Extended Echo Request - ICMPTypeExtendedEchoReply ICMPType = 43 // Extended Echo Reply -) - -// Internet Control Message Protocol (ICMP) Parameters, Updated: 2018-02-26 -var icmpTypes = map[ICMPType]string{ - 0: "echo reply", - 3: "destination unreachable", - 5: "redirect", - 8: "echo", - 9: "router advertisement", - 10: "router solicitation", - 11: "time exceeded", - 12: "parameter problem", - 13: "timestamp", - 14: "timestamp reply", - 40: "photuris", - 42: "extended echo request", - 43: "extended echo reply", -} diff --git a/vendor/golang.org/x/net/ipv4/icmp.go b/vendor/golang.org/x/net/ipv4/icmp.go deleted file mode 100644 index 9902bb3d2..000000000 --- a/vendor/golang.org/x/net/ipv4/icmp.go +++ /dev/null @@ -1,57 +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 ipv4 - -import "golang.org/x/net/internal/iana" - -// An ICMPType represents a type of ICMP message. -type ICMPType int - -func (typ ICMPType) String() string { - s, ok := icmpTypes[typ] - if !ok { - return "" - } - return s -} - -// Protocol returns the ICMPv4 protocol number. -func (typ ICMPType) Protocol() int { - return iana.ProtocolICMP -} - -// An ICMPFilter represents an ICMP message filter for incoming -// 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 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 { - icmpFilter -} - -// Accept accepts incoming ICMP packets including the type field value -// typ. -func (f *ICMPFilter) Accept(typ ICMPType) { - f.accept(typ) -} - -// Block blocks incoming ICMP packets including the type field value -// typ. -func (f *ICMPFilter) Block(typ ICMPType) { - f.block(typ) -} - -// SetAll sets the filter action to the filter. -func (f *ICMPFilter) SetAll(block bool) { - f.setAll(block) -} - -// WillBlock reports whether the ICMP type will be blocked. -func (f *ICMPFilter) WillBlock(typ ICMPType) bool { - return f.willBlock(typ) -} diff --git a/vendor/golang.org/x/net/ipv4/icmp_linux.go b/vendor/golang.org/x/net/ipv4/icmp_linux.go deleted file mode 100644 index 6e1c5c80a..000000000 --- a/vendor/golang.org/x/net/ipv4/icmp_linux.go +++ /dev/null @@ -1,25 +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 - -func (f *icmpFilter) accept(typ ICMPType) { - f.Data &^= 1 << (uint32(typ) & 31) -} - -func (f *icmpFilter) block(typ ICMPType) { - f.Data |= 1 << (uint32(typ) & 31) -} - -func (f *icmpFilter) setAll(block bool) { - if block { - f.Data = 1<<32 - 1 - } else { - f.Data = 0 - } -} - -func (f *icmpFilter) willBlock(typ ICMPType) bool { - return f.Data&(1<<(uint32(typ)&31)) != 0 -} diff --git a/vendor/golang.org/x/net/ipv4/icmp_stub.go b/vendor/golang.org/x/net/ipv4/icmp_stub.go deleted file mode 100644 index c2c4ce7ff..000000000 --- a/vendor/golang.org/x/net/ipv4/icmp_stub.go +++ /dev/null @@ -1,25 +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. - -//go:build !linux - -package ipv4 - -const sizeofICMPFilter = 0x0 - -type icmpFilter struct { -} - -func (f *icmpFilter) accept(typ ICMPType) { -} - -func (f *icmpFilter) block(typ ICMPType) { -} - -func (f *icmpFilter) setAll(block bool) { -} - -func (f *icmpFilter) willBlock(typ ICMPType) bool { - return false -} diff --git a/vendor/golang.org/x/net/ipv4/packet.go b/vendor/golang.org/x/net/ipv4/packet.go deleted file mode 100644 index 7d784e06d..000000000 --- a/vendor/golang.org/x/net/ipv4/packet.go +++ /dev/null @@ -1,117 +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" - - "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 { - *net.IPConn - *socket.Conn - rawOpt -} - -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 -// 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, errInvalidConn - } - c.rawOpt.RLock() - m := socket.Message{ - Buffers: [][]byte{b}, - OOB: NewControlMessage(c.rawOpt.cflags), - } - c.rawOpt.RUnlock() - if err := c.RecvMsg(&m, 0); err != nil { - return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - var hs []byte - if hs, p, err = slicePacket(b[:m.N]); err != nil { - return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - if h, err = ParseHeader(hs); err != nil { - return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - if m.NN > 0 { - if compatFreeBSD32 { - adjustFreeBSD32(&m) - } - cm = new(ControlMessage) - if err := cm.Parse(m.OOB[:m.NN]); err != nil { - return nil, nil, nil, &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err} - } - } - if src, ok := m.Addr.(*net.IPAddr); ok && cm != nil { - cm.Src = src.IP - } - return -} - -func slicePacket(b []byte) (h, p []byte, err error) { - if len(b) < HeaderLen { - return nil, nil, errHeaderTooShort - } - hdrlen := int(b[0]&0x0f) << 2 - return b[:hdrlen], b[hdrlen:], nil -} - -// WriteTo writes an IPv4 datagram through the endpoint c, copying the -// 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 -// may be nil if control of the outgoing datagram is not required. -// -// The IPv4 header h must contain appropriate fields that include: -// -// Version = -// Len = -// TOS = -// TotalLen = -// ID = platform sets an appropriate value if ID is zero -// FragOff = -// TTL = -// Protocol = -// Checksum = platform sets an appropriate value if Checksum is zero -// Src = platform sets an appropriate value if Src is nil -// Dst = -// Options = optional -func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error { - if !c.ok() { - return errInvalidConn - } - m := socket.Message{ - OOB: cm.Marshal(), - } - wh, err := h.Marshal() - if err != nil { - return err - } - m.Buffers = [][]byte{wh, p} - dst := new(net.IPAddr) - if cm != nil { - if ip := cm.Dst.To4(); ip != nil { - dst.IP = ip - } - } - if dst.IP == nil { - dst.IP = h.Dst - } - m.Addr = dst - if err := c.SendMsg(&m, 0); err != nil { - return &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Addr: opAddr(dst), Err: err} - } - return nil -} diff --git a/vendor/golang.org/x/net/ipv4/payload.go b/vendor/golang.org/x/net/ipv4/payload.go deleted file mode 100644 index f95f811ac..000000000 --- a/vendor/golang.org/x/net/ipv4/payload.go +++ /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. - -package ipv4 - -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 && c.Conn != nil } diff --git a/vendor/golang.org/x/net/ipv4/payload_cmsg.go b/vendor/golang.org/x/net/ipv4/payload_cmsg.go deleted file mode 100644 index 91c685e8f..000000000 --- a/vendor/golang.org/x/net/ipv4/payload_cmsg.go +++ /dev/null @@ -1,84 +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. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos - -package ipv4 - -import ( - "net" - - "golang.org/x/net/internal/socket" -) - -// ReadFrom reads a payload of the received IPv4 datagram, from the -// 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, errInvalidConn - } - c.rawOpt.RLock() - m := socket.Message{ - OOB: NewControlMessage(c.rawOpt.cflags), - } - c.rawOpt.RUnlock() - switch c.PacketConn.(type) { - case *net.UDPConn: - m.Buffers = [][]byte{b} - if err := c.RecvMsg(&m, 0); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - case *net.IPConn: - h := make([]byte, HeaderLen) - m.Buffers = [][]byte{h, b} - if err := c.RecvMsg(&m, 0); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - hdrlen := int(h[0]&0x0f) << 2 - if hdrlen > len(h) { - d := hdrlen - len(h) - copy(b, b[d:]) - m.N -= d - } else { - m.N -= hdrlen - } - default: - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType} - } - if m.NN > 0 { - if compatFreeBSD32 { - adjustFreeBSD32(&m) - } - cm = new(ControlMessage) - if err := cm.Parse(m.OOB[:m.NN]); err != nil { - return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err} - } - cm.Src = netAddrToIP4(m.Addr) - } - return m.N, cm, m.Addr, nil -} - -// 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 -// the datagram path and the outgoing interface to be specified. -// 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, errInvalidConn - } - m := socket.Message{ - Buffers: [][]byte{b}, - OOB: cm.Marshal(), - Addr: dst, - } - err = c.SendMsg(&m, 0) - if err != nil { - err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err} - } - return m.N, err -} diff --git a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go b/vendor/golang.org/x/net/ipv4/payload_nocmsg.go deleted file mode 100644 index 2afd4b50e..000000000 --- a/vendor/golang.org/x/net/ipv4/payload_nocmsg.go +++ /dev/null @@ -1,39 +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. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !zos - -package ipv4 - -import "net" - -// ReadFrom reads a payload of the received IPv4 datagram, from the -// 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, errInvalidConn - } - if n, src, err = c.PacketConn.ReadFrom(b); err != nil { - return 0, nil, nil, err - } - return -} - -// 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 -// the datagram path and the outgoing interface to be specified. -// 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, errInvalidConn - } - if dst == nil { - return 0, errMissingAddress - } - return c.PacketConn.WriteTo(b, dst) -} diff --git a/vendor/golang.org/x/net/ipv4/sockopt.go b/vendor/golang.org/x/net/ipv4/sockopt.go deleted file mode 100644 index 22e90c039..000000000 --- a/vendor/golang.org/x/net/ipv4/sockopt.go +++ /dev/null @@ -1,44 +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 "golang.org/x/net/internal/socket" - -// Sticky socket options -const ( - ssoTOS = iota // header field for unicast packet - ssoTTL // header field for unicast packet - ssoMulticastTTL // header field for multicast packet - ssoMulticastInterface // outbound interface for multicast packet - ssoMulticastLoopback // loopback for multicast packet - ssoReceiveTTL // header field on received packet - ssoReceiveDst // header field on received packet - ssoReceiveInterface // inbound interface on received packet - ssoPacketInfo // incbound or outbound packet path - ssoHeaderPrepend // ipv4 header prepend - ssoStripHeader // strip ipv4 header - ssoICMPFilter // icmp filter - ssoJoinGroup // any-source multicast - ssoLeaveGroup // any-source multicast - ssoJoinSourceGroup // source-specific multicast - ssoLeaveSourceGroup // source-specific multicast - ssoBlockSourceGroup // any-source or source-specific multicast - ssoUnblockSourceGroup // any-source or source-specific multicast - ssoAttachFilter // attach BPF for filtering inbound traffic -) - -// Sticky socket option value types -const ( - ssoTypeIPMreq = iota + 1 - ssoTypeIPMreqn - ssoTypeGroupReq - ssoTypeGroupSourceReq -) - -// A sockOpt represents a binding for sticky socket option. -type sockOpt struct { - socket.Option - typ int // hint for option value type; optional -} diff --git a/vendor/golang.org/x/net/ipv4/sockopt_posix.go b/vendor/golang.org/x/net/ipv4/sockopt_posix.go deleted file mode 100644 index 82e2c3783..000000000 --- a/vendor/golang.org/x/net/ipv4/sockopt_posix.go +++ /dev/null @@ -1,71 +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. - -//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || windows || zos - -package ipv4 - -import ( - "net" - "unsafe" - - "golang.org/x/net/bpf" - "golang.org/x/net/internal/socket" -) - -func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) { - switch so.typ { - case ssoTypeIPMreqn: - return so.getIPMreqn(c) - default: - return so.getMulticastIf(c) - } -} - -func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error { - switch so.typ { - case ssoTypeIPMreqn: - return so.setIPMreqn(c, ifi, nil) - default: - return so.setMulticastIf(c, ifi) - } -} - -func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) { - b := make([]byte, so.Len) - n, err := so.Get(c, b) - if err != nil { - return nil, err - } - if n != sizeofICMPFilter { - return nil, errNotImplemented - } - return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil -} - -func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error { - b := (*[sizeofICMPFilter]byte)(unsafe.Pointer(f))[:sizeofICMPFilter] - return so.Set(c, b) -} - -func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - switch so.typ { - case ssoTypeIPMreq: - return so.setIPMreq(c, ifi, grp) - case ssoTypeIPMreqn: - return so.setIPMreqn(c, ifi, grp) - case ssoTypeGroupReq: - return so.setGroupReq(c, ifi, grp) - default: - return errNotImplemented - } -} - -func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { - return so.setGroupSourceReq(c, ifi, grp, src) -} - -func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error { - return so.setAttachFilter(c, f) -} diff --git a/vendor/golang.org/x/net/ipv4/sockopt_stub.go b/vendor/golang.org/x/net/ipv4/sockopt_stub.go deleted file mode 100644 index 840108bf7..000000000 --- a/vendor/golang.org/x/net/ipv4/sockopt_stub.go +++ /dev/null @@ -1,42 +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. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos - -package ipv4 - -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, errNotImplemented -} - -func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error { - return errNotImplemented -} - -func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) { - return nil, errNotImplemented -} - -func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error { - return errNotImplemented -} - -func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errNotImplemented -} - -func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { - return errNotImplemented -} - -func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error { - return errNotImplemented -} diff --git a/vendor/golang.org/x/net/ipv4/sys_aix.go b/vendor/golang.org/x/net/ipv4/sys_aix.go deleted file mode 100644 index 9244a68a3..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_aix.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Added for go1.11 compatibility -//go:build aix - -package ipv4 - -import ( - "net" - "syscall" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -// IP_RECVIF is defined on AIX but doesn't work. IP_RECVINTERFACE must be used instead. -const sockoptReceiveInterface = unix.IP_RECVINTERFACE - -var ( - ctlOpts = [ctlMax]ctlOpt{ - ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL}, - ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, - ctlInterface: {unix.IP_RECVINTERFACE, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, - } - - sockOpts = map[int]*sockOpt{ - ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}}, - ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}}, - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}}, - ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}}, - ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}}, - ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVINTERFACE, Len: 4}}, - ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - } -) diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreq.go b/vendor/golang.org/x/net/ipv4/sys_asmreq.go deleted file mode 100644 index 645f254c6..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_asmreq.go +++ /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. - -//go:build aix || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || windows - -package ipv4 - -import ( - "errors" - "net" - "unsafe" - - "golang.org/x/net/internal/socket" -) - -var errNoSuchInterface = errors.New("no such interface") - -func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - mreq := ipMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}} - if err := setIPMreqInterface(&mreq, ifi); err != nil { - return err - } - b := (*[sizeofIPMreq]byte)(unsafe.Pointer(&mreq))[:sizeofIPMreq] - return so.Set(c, b) -} - -func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) { - var b [4]byte - if _, err := so.Get(c, b[:]); err != nil { - return nil, err - } - ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3])) - if err != nil { - return nil, err - } - return ifi, nil -} - -func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error { - ip, err := netInterfaceToIP4(ifi) - if err != nil { - return err - } - var b [4]byte - copy(b[:], ip) - return so.Set(c, b[:]) -} - -func setIPMreqInterface(mreq *ipMreq, 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/sys_asmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go deleted file mode 100644 index 48cfb6db2..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !windows - -package ipv4 - -import ( - "net" - - "golang.org/x/net/internal/socket" -) - -func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errNotImplemented -} - -func (so *sockOpt) getMulticastIf(c *socket.Conn) (*net.Interface, error) { - return nil, errNotImplemented -} - -func (so *sockOpt) setMulticastIf(c *socket.Conn, ifi *net.Interface) error { - return errNotImplemented -} diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn.go deleted file mode 100644 index 0b27b632f..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_asmreqn.go +++ /dev/null @@ -1,44 +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. - -//go:build darwin || freebsd || linux - -package ipv4 - -import ( - "net" - "unsafe" - - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) { - b := make([]byte, so.Len) - if _, err := so.Get(c, b); err != nil { - return nil, err - } - mreqn := (*unix.IPMreqn)(unsafe.Pointer(&b[0])) - if mreqn.Ifindex == 0 { - return nil, nil - } - ifi, err := net.InterfaceByIndex(int(mreqn.Ifindex)) - if err != nil { - return nil, err - } - return ifi, nil -} - -func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - var mreqn unix.IPMreqn - if ifi != nil { - mreqn.Ifindex = int32(ifi.Index) - } - if grp != nil { - mreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]} - } - b := (*[unix.SizeofIPMreqn]byte)(unsafe.Pointer(&mreqn))[:unix.SizeofIPMreqn] - return so.Set(c, b) -} diff --git a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go b/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go deleted file mode 100644 index 303a5e2e6..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go +++ /dev/null @@ -1,21 +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. - -//go:build !darwin && !freebsd && !linux - -package ipv4 - -import ( - "net" - - "golang.org/x/net/internal/socket" -) - -func (so *sockOpt) getIPMreqn(c *socket.Conn) (*net.Interface, error) { - return nil, errNotImplemented -} - -func (so *sockOpt) setIPMreqn(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errNotImplemented -} diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf.go b/vendor/golang.org/x/net/ipv4/sys_bpf.go deleted file mode 100644 index 1b4780df4..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_bpf.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build linux - -package ipv4 - -import ( - "unsafe" - - "golang.org/x/net/bpf" - "golang.org/x/net/internal/socket" - "golang.org/x/sys/unix" -) - -func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error { - prog := unix.SockFprog{ - Len: uint16(len(f)), - Filter: (*unix.SockFilter)(unsafe.Pointer(&f[0])), - } - b := (*[unix.SizeofSockFprog]byte)(unsafe.Pointer(&prog))[:unix.SizeofSockFprog] - return so.Set(c, b) -} diff --git a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go b/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go deleted file mode 100644 index b1f779b49..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_bpf_stub.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !linux - -package ipv4 - -import ( - "golang.org/x/net/bpf" - "golang.org/x/net/internal/socket" -) - -func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error { - return errNotImplemented -} diff --git a/vendor/golang.org/x/net/ipv4/sys_bsd.go b/vendor/golang.org/x/net/ipv4/sys_bsd.go deleted file mode 100644 index b7b032d26..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_bsd.go +++ /dev/null @@ -1,41 +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. - -//go:build netbsd || openbsd - -package ipv4 - -import ( - "net" - "syscall" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -const sockoptReceiveInterface = unix.IP_RECVIF - -var ( - ctlOpts = [ctlMax]ctlOpt{ - ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL}, - ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, - ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, - } - - sockOpts = map[int]*sockOpt{ - ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}}, - ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}}, - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}}, - ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}}, - ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}}, - ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}}, - ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - } -) diff --git a/vendor/golang.org/x/net/ipv4/sys_darwin.go b/vendor/golang.org/x/net/ipv4/sys_darwin.go deleted file mode 100644 index cac6f3cac..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_darwin.go +++ /dev/null @@ -1,69 +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" - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -const sockoptReceiveInterface = unix.IP_RECVIF - -var ( - ctlOpts = [ctlMax]ctlOpt{ - ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL}, - ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, - ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, - ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo}, - } - - sockOpts = map[int]*sockOpt{ - ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}}, - ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}}, - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}}, - ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}}, - ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}}, - ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}}, - ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}}, - ssoStripHeader: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_STRIPHDR, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}}, - } -) - -func (pi *inetPktinfo) setIfindex(i int) { - pi.Ifindex = uint32(i) -} - -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 *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 = (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132)) - sa.Len = sizeofSockaddrInet - sa.Family = syscall.AF_INET - copy(sa.Addr[:], src) -} diff --git a/vendor/golang.org/x/net/ipv4/sys_dragonfly.go b/vendor/golang.org/x/net/ipv4/sys_dragonfly.go deleted file mode 100644 index 0620d0e1e..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_dragonfly.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ipv4 - -import ( - "net" - "syscall" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -const sockoptReceiveInterface = unix.IP_RECVIF - -var ( - ctlOpts = [ctlMax]ctlOpt{ - ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL}, - ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, - ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, - } - - sockOpts = map[int]*sockOpt{ - ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}}, - ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}}, - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}}, - ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}}, - ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}}, - ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}}, - ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - } -) diff --git a/vendor/golang.org/x/net/ipv4/sys_freebsd.go b/vendor/golang.org/x/net/ipv4/sys_freebsd.go deleted file mode 100644 index 896122875..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_freebsd.go +++ /dev/null @@ -1,80 +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" - "runtime" - "strings" - "syscall" - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -const sockoptReceiveInterface = unix.IP_RECVIF - -var ( - ctlOpts = [ctlMax]ctlOpt{ - ctlTTL: {unix.IP_RECVTTL, 1, marshalTTL, parseTTL}, - ctlDst: {unix.IP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, - ctlInterface: {unix.IP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, - } - - sockOpts = map[int]*sockOpt{ - ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}}, - ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}}, - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}}, - ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}}, - ssoReceiveDst: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVDSTADDR, Len: 4}}, - ssoReceiveInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVIF, Len: 4}}, - ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - } -) - -func init() { - freebsdVersion, _ = syscall.SysctlUint32("kern.osreldate") - if freebsdVersion >= 1000000 { - sockOpts[ssoMulticastInterface] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn} - } - if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" { - archs, _ := syscall.Sysctl("kern.supported_archs") - for _, s := range strings.Fields(archs) { - if s == "amd64" { - compatFreeBSD32 = true - break - } - } - } -} - -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 *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 = (*sockaddrInet)(unsafe.Pointer(&gsr.Source)) - sa.Len = sizeofSockaddrInet - sa.Family = syscall.AF_INET - copy(sa.Addr[:], src) -} diff --git a/vendor/golang.org/x/net/ipv4/sys_linux.go b/vendor/golang.org/x/net/ipv4/sys_linux.go deleted file mode 100644 index 4588a5f3e..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_linux.go +++ /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. - -package ipv4 - -import ( - "net" - "syscall" - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -var ( - ctlOpts = [ctlMax]ctlOpt{ - ctlTTL: {unix.IP_TTL, 1, marshalTTL, parseTTL}, - ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo}, - } - - sockOpts = map[int]*sockOpt{ - ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}}, - ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}}, - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 4}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: unix.SizeofIPMreqn}, typ: ssoTypeIPMreqn}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 4}}, - ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}}, - ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_PKTINFO, Len: 4}}, - ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}}, - ssoICMPFilter: {Option: socket.Option{Level: iana.ProtocolReserved, Name: unix.ICMP_FILTER, Len: sizeofICMPFilter}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoAttachFilter: {Option: socket.Option{Level: unix.SOL_SOCKET, Name: unix.SO_ATTACH_FILTER, Len: unix.SizeofSockFprog}}, - } -) - -func (pi *inetPktinfo) setIfindex(i int) { - pi.Ifindex = int32(i) -} - -func (gr *groupReq) setGroup(grp net.IP) { - sa := (*sockaddrInet)(unsafe.Pointer(&gr.Group)) - sa.Family = syscall.AF_INET - copy(sa.Addr[:], grp) -} - -func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) { - sa := (*sockaddrInet)(unsafe.Pointer(&gsr.Group)) - sa.Family = syscall.AF_INET - copy(sa.Addr[:], grp) - 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_solaris.go b/vendor/golang.org/x/net/ipv4/sys_solaris.go deleted file mode 100644 index 0bb9f3e36..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_solaris.go +++ /dev/null @@ -1,61 +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 ipv4 - -import ( - "net" - "syscall" - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -const sockoptReceiveInterface = unix.IP_RECVIF - -var ( - ctlOpts = [ctlMax]ctlOpt{ - ctlTTL: {unix.IP_RECVTTL, 4, marshalTTL, parseTTL}, - ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo}, - } - - sockOpts = map[int]sockOpt{ - ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TOS, Len: 4}}, - ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_TTL, Len: 4}}, - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}}, - ssoReceiveTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVTTL, Len: 4}}, - ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}}, - ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_HDRINCL, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - } -) - -func (pi *inetPktinfo) setIfindex(i int) { - pi.Ifindex = uint32(i) -} - -func (gr *groupReq) setGroup(grp net.IP) { - sa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4)) - sa.Family = syscall.AF_INET - copy(sa.Addr[:], grp) -} - -func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) { - sa := (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4)) - sa.Family = syscall.AF_INET - copy(sa.Addr[:], grp) - sa = (*sockaddrInet)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 260)) - sa.Family = syscall.AF_INET - copy(sa.Addr[:], src) -} diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq.go deleted file mode 100644 index a295e15ea..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_ssmreq.go +++ /dev/null @@ -1,52 +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. - -//go:build darwin || freebsd || linux || solaris - -package ipv4 - -import ( - "net" - "unsafe" - - "golang.org/x/net/internal/socket" -) - -func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - var gr groupReq - if ifi != nil { - gr.Interface = uint32(ifi.Index) - } - gr.setGroup(grp) - var b []byte - if compatFreeBSD32 { - var d [sizeofGroupReq + 4]byte - s := (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr)) - copy(d[:4], s[:4]) - copy(d[8:], s[4:]) - b = d[:] - } else { - b = (*[sizeofGroupReq]byte)(unsafe.Pointer(&gr))[:sizeofGroupReq] - } - return so.Set(c, b) -} - -func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { - var gsr groupSourceReq - if ifi != nil { - gsr.Interface = uint32(ifi.Index) - } - gsr.setSourceGroup(grp, src) - var b []byte - if compatFreeBSD32 { - var d [sizeofGroupSourceReq + 4]byte - s := (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr)) - copy(d[:4], s[:4]) - copy(d[8:], s[4:]) - b = d[:] - } else { - b = (*[sizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr))[:sizeofGroupSourceReq] - } - return so.Set(c, b) -} diff --git a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go b/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go deleted file mode 100644 index 74bd454e2..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go +++ /dev/null @@ -1,21 +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. - -//go:build !darwin && !freebsd && !linux && !solaris - -package ipv4 - -import ( - "net" - - "golang.org/x/net/internal/socket" -) - -func (so *sockOpt) setGroupReq(c *socket.Conn, ifi *net.Interface, grp net.IP) error { - return errNotImplemented -} - -func (so *sockOpt) setGroupSourceReq(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error { - return errNotImplemented -} diff --git a/vendor/golang.org/x/net/ipv4/sys_stub.go b/vendor/golang.org/x/net/ipv4/sys_stub.go deleted file mode 100644 index 20af4074c..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_stub.go +++ /dev/null @@ -1,13 +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. - -//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows && !zos - -package ipv4 - -var ( - ctlOpts = [ctlMax]ctlOpt{} - - sockOpts = map[int]*sockOpt{} -) diff --git a/vendor/golang.org/x/net/ipv4/sys_windows.go b/vendor/golang.org/x/net/ipv4/sys_windows.go deleted file mode 100644 index c5e950633..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_windows.go +++ /dev/null @@ -1,44 +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 ( - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/windows" -) - -const ( - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc -) - -type ipMreq struct { - Multiaddr [4]byte - Interface [4]byte -} - -type ipMreqSource struct { - Multiaddr [4]byte - Sourceaddr [4]byte - Interface [4]byte -} - -// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms738586(v=vs.85).aspx -var ( - ctlOpts = [ctlMax]ctlOpt{} - - sockOpts = map[int]*sockOpt{ - ssoTOS: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_TOS, Len: 4}}, - ssoTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_TTL, Len: 4}}, - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_TTL, Len: 4}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_IF, Len: 4}}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_MULTICAST_LOOP, Len: 4}}, - ssoHeaderPrepend: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_HDRINCL, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_ADD_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: windows.IP_DROP_MEMBERSHIP, Len: sizeofIPMreq}, typ: ssoTypeIPMreq}, - } -) diff --git a/vendor/golang.org/x/net/ipv4/sys_zos.go b/vendor/golang.org/x/net/ipv4/sys_zos.go deleted file mode 100644 index be2064098..000000000 --- a/vendor/golang.org/x/net/ipv4/sys_zos.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ipv4 - -import ( - "net" - "syscall" - "unsafe" - - "golang.org/x/net/internal/iana" - "golang.org/x/net/internal/socket" - - "golang.org/x/sys/unix" -) - -var ( - ctlOpts = [ctlMax]ctlOpt{ - ctlPacketInfo: {unix.IP_PKTINFO, sizeofInetPktinfo, marshalPacketInfo, parsePacketInfo}, - } - - sockOpts = map[int]*sockOpt{ - ssoMulticastTTL: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_TTL, Len: 1}}, - ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_IF, Len: 4}}, - ssoMulticastLoopback: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_MULTICAST_LOOP, Len: 1}}, - ssoPacketInfo: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.IP_RECVPKTINFO, Len: 4}}, - ssoJoinGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoLeaveGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}, - ssoJoinSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoLeaveSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoBlockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - ssoUnblockSourceGroup: {Option: socket.Option{Level: iana.ProtocolIP, Name: unix.MCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}, - } -) - -func (pi *inetPktinfo) setIfindex(i int) { - pi.Ifindex = uint32(i) -} - -func (gr *groupReq) setGroup(grp net.IP) { - sa := (*sockaddrInet4)(unsafe.Pointer(&gr.Group)) - sa.Family = syscall.AF_INET - sa.Len = sizeofSockaddrInet4 - copy(sa.Addr[:], grp) -} - -func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) { - sa := (*sockaddrInet4)(unsafe.Pointer(&gsr.Group)) - sa.Family = syscall.AF_INET - sa.Len = sizeofSockaddrInet4 - copy(sa.Addr[:], grp) - sa = (*sockaddrInet4)(unsafe.Pointer(&gsr.Source)) - sa.Family = syscall.AF_INET - sa.Len = sizeofSockaddrInet4 - copy(sa.Addr[:], src) -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go deleted file mode 100644 index dd454025c..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_aix.go - -// Added for go1.11 compatibility -//go:build aix - -package ipv4 - -const ( - sizeofIPMreq = 0x8 -) - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_darwin.go b/vendor/golang.org/x/net/ipv4/zsys_darwin.go deleted file mode 100644 index 6c1b70564..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_darwin.go +++ /dev/null @@ -1,59 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_darwin.go - -package ipv4 - -const ( - sizeofSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x84 - sizeofGroupSourceReq = 0x104 -) - -type sockaddrStorage struct { - Len uint8 - Family uint8 - X__ss_pad1 [6]int8 - X__ss_align int64 - X__ss_pad2 [112]int8 -} - -type sockaddrInet struct { - Len uint8 - Family uint8 - 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 ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -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 [128]byte -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [128]byte - Pad_cgo_1 [128]byte -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go b/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go deleted file mode 100644 index 2155df130..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_dragonfly.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_dragonfly.go - -package ipv4 - -const ( - sizeofIPMreq = 0x8 -) - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go deleted file mode 100644 index ae40482a8..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go +++ /dev/null @@ -1,52 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package ipv4 - -const ( - sizeofSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x84 - sizeofGroupSourceReq = 0x104 -) - -type sockaddrStorage struct { - Len uint8 - Family uint8 - X__ss_pad1 [6]int8 - X__ss_align int64 - X__ss_pad2 [112]int8 -} - -type sockaddrInet struct { - Len uint8 - Family uint8 - Port uint16 - Addr [4]byte /* in_addr */ - Zero [8]int8 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr [4]byte /* in_addr */ - Sourceaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type groupReq struct { - Interface uint32 - Group sockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Group sockaddrStorage - Source sockaddrStorage -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go deleted file mode 100644 index 901818671..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go +++ /dev/null @@ -1,54 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package ipv4 - -const ( - sizeofSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 -) - -type sockaddrStorage struct { - Len uint8 - Family uint8 - X__ss_pad1 [6]int8 - X__ss_align int64 - X__ss_pad2 [112]int8 -} - -type sockaddrInet struct { - Len uint8 - Family uint8 - Port uint16 - Addr [4]byte /* in_addr */ - Zero [8]int8 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -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 [4]byte - Group sockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group sockaddrStorage - Source sockaddrStorage -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go deleted file mode 100644 index 901818671..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go +++ /dev/null @@ -1,54 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package ipv4 - -const ( - sizeofSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 -) - -type sockaddrStorage struct { - Len uint8 - Family uint8 - X__ss_pad1 [6]int8 - X__ss_align int64 - X__ss_pad2 [112]int8 -} - -type sockaddrInet struct { - Len uint8 - Family uint8 - Port uint16 - Addr [4]byte /* in_addr */ - Zero [8]int8 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -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 [4]byte - Group sockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group sockaddrStorage - Source sockaddrStorage -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go deleted file mode 100644 index 0feb9a753..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go +++ /dev/null @@ -1,52 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package ipv4 - -const ( - sizeofSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 -) - -type sockaddrStorage struct { - Len uint8 - Family uint8 - X__ss_pad1 [6]uint8 - X__ss_align int64 - X__ss_pad2 [112]uint8 -} - -type sockaddrInet struct { - Len uint8 - Family uint8 - Port uint16 - Addr [4]byte /* in_addr */ - Zero [8]uint8 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr [4]byte /* in_addr */ - Sourceaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type groupReq struct { - Interface uint32 - Group sockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Group sockaddrStorage - Source sockaddrStorage -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go deleted file mode 100644 index 0feb9a753..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go +++ /dev/null @@ -1,52 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_freebsd.go - -package ipv4 - -const ( - sizeofSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 -) - -type sockaddrStorage struct { - Len uint8 - Family uint8 - X__ss_pad1 [6]uint8 - X__ss_align int64 - X__ss_pad2 [112]uint8 -} - -type sockaddrInet struct { - Len uint8 - Family uint8 - Port uint16 - Addr [4]byte /* in_addr */ - Zero [8]uint8 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr [4]byte /* in_addr */ - Sourceaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type groupReq struct { - Interface uint32 - Group sockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Group sockaddrStorage - Source sockaddrStorage -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_386.go b/vendor/golang.org/x/net/ipv4/zsys_linux_386.go deleted file mode 100644 index d510357ca..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_386.go +++ /dev/null @@ -1,72 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x84 - sizeofGroupSourceReq = 0x104 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go deleted file mode 100644 index eb10cc79b..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go deleted file mode 100644 index d510357ca..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_arm.go +++ /dev/null @@ -1,72 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x84 - sizeofGroupSourceReq = 0x104 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go deleted file mode 100644 index eb10cc79b..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go deleted file mode 100644 index 54f9e1394..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_loong64.go +++ /dev/null @@ -1,76 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -//go:build loong64 - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go deleted file mode 100644 index d510357ca..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips.go +++ /dev/null @@ -1,72 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x84 - sizeofGroupSourceReq = 0x104 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go deleted file mode 100644 index eb10cc79b..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go deleted file mode 100644 index eb10cc79b..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go b/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go deleted file mode 100644 index d510357ca..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go +++ /dev/null @@ -1,72 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x84 - sizeofGroupSourceReq = 0x104 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go deleted file mode 100644 index 29202e401..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go +++ /dev/null @@ -1,72 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x84 - sizeofGroupSourceReq = 0x104 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]uint8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go deleted file mode 100644 index eb10cc79b..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go b/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go deleted file mode 100644 index eb10cc79b..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go b/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go deleted file mode 100644 index 78374a525..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go +++ /dev/null @@ -1,76 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -//go:build riscv64 - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go b/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go deleted file mode 100644 index eb10cc79b..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go +++ /dev/null @@ -1,74 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_linux.go - -package ipv4 - -const ( - sizeofKernelSockaddrStorage = 0x80 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - sizeofSockExtendedErr = 0x10 - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x88 - sizeofGroupSourceReq = 0x108 - - sizeofICMPFilter = 0x4 -) - -type kernelSockaddrStorage struct { - Family uint16 - X__data [126]int8 -} - -type sockaddrInet struct { - Family uint16 - Port uint16 - Addr [4]byte /* in_addr */ - X__pad [8]uint8 -} - -type inetPktinfo struct { - Ifindex int32 - Spec_dst [4]byte /* in_addr */ - Addr [4]byte /* in_addr */ -} - -type sockExtendedErr struct { - Errno uint32 - Origin uint8 - Type uint8 - Code uint8 - Pad uint8 - Info uint32 - Data uint32 -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -type ipMreqSource struct { - Multiaddr uint32 - Interface uint32 - Sourceaddr uint32 -} - -type groupReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - Pad_cgo_0 [4]byte - Group kernelSockaddrStorage - Source kernelSockaddrStorage -} - -type icmpFilter struct { - Data uint32 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_netbsd.go b/vendor/golang.org/x/net/ipv4/zsys_netbsd.go deleted file mode 100644 index a2ef2f6d6..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_netbsd.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_netbsd.go - -package ipv4 - -const ( - sizeofIPMreq = 0x8 -) - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_openbsd.go b/vendor/golang.org/x/net/ipv4/zsys_openbsd.go deleted file mode 100644 index b293a338f..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_openbsd.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_openbsd.go - -package ipv4 - -const ( - sizeofIPMreq = 0x8 -) - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_solaris.go b/vendor/golang.org/x/net/ipv4/zsys_solaris.go deleted file mode 100644 index e1a961bb6..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_solaris.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_solaris.go - -package ipv4 - -const ( - sizeofSockaddrStorage = 0x100 - sizeofSockaddrInet = 0x10 - sizeofInetPktinfo = 0xc - - sizeofIPMreq = 0x8 - sizeofIPMreqSource = 0xc - sizeofGroupReq = 0x104 - sizeofGroupSourceReq = 0x204 -) - -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 ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} - -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 -} diff --git a/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go b/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go deleted file mode 100644 index 692abf688..000000000 --- a/vendor/golang.org/x/net/ipv4/zsys_zos_s390x.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Hand edited based on zerrors_zos_s390x.go -// TODO(Bill O'Farrell): auto-generate. - -package ipv4 - -const ( - sizeofIPMreq = 8 - sizeofSockaddrInet4 = 16 - sizeofSockaddrStorage = 128 - sizeofGroupReq = 136 - sizeofGroupSourceReq = 264 - sizeofInetPktinfo = 8 -) - -type sockaddrInet4 struct { - Len uint8 - Family uint8 - Port uint16 - Addr [4]byte - Zero [8]uint8 -} - -type inetPktinfo struct { - Addr [4]byte - Ifindex uint32 -} - -type sockaddrStorage struct { - Len uint8 - Family byte - ss_pad1 [6]byte - ss_align int64 - ss_pad2 [112]byte -} - -type groupReq struct { - Interface uint32 - reserved uint32 - Group sockaddrStorage -} - -type groupSourceReq struct { - Interface uint32 - reserved uint32 - Group sockaddrStorage - Source sockaddrStorage -} - -type ipMreq struct { - Multiaddr [4]byte /* in_addr */ - Interface [4]byte /* in_addr */ -} diff --git a/vendor/github.com/d2g/dhcp4/LICENSE b/vendor/golang.org/x/sync/LICENSE similarity index 90% rename from vendor/github.com/d2g/dhcp4/LICENSE rename to vendor/golang.org/x/sync/LICENSE index f7d058a35..2a7cf70da 100644 --- a/vendor/github.com/d2g/dhcp4/LICENSE +++ b/vendor/golang.org/x/sync/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013 Skagerrak Software Limited. All rights reserved. +Copyright 2009 The Go Authors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +10,7 @@ notice, this list of conditions and the following disclaimer. copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Skagerrak Software Limited nor the names of its + * Neither the name of Google LLC nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -24,4 +24,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/golang.org/x/sync/PATENTS b/vendor/golang.org/x/sync/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/vendor/golang.org/x/sync/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go new file mode 100644 index 000000000..948a3ee63 --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -0,0 +1,135 @@ +// 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 errgroup provides synchronization, error propagation, and Context +// cancelation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. +package errgroup + +import ( + "context" + "fmt" + "sync" +) + +type token struct{} + +// A Group is a collection of goroutines working on subtasks that are part of +// the same overall task. +// +// A zero Group is valid, has no limit on the number of active goroutines, +// and does not cancel on error. +type Group struct { + cancel func(error) + + wg sync.WaitGroup + + sem chan token + + errOnce sync.Once + err error +} + +func (g *Group) done() { + if g.sem != nil { + <-g.sem + } + g.wg.Done() +} + +// WithContext returns a new Group and an associated Context derived from ctx. +// +// The derived Context is canceled the first time a function passed to Go +// returns a non-nil error or the first time Wait returns, whichever occurs +// first. +func WithContext(ctx context.Context) (*Group, context.Context) { + ctx, cancel := withCancelCause(ctx) + return &Group{cancel: cancel}, ctx +} + +// Wait blocks until all function calls from the Go method have returned, then +// returns the first non-nil error (if any) from them. +func (g *Group) Wait() error { + g.wg.Wait() + if g.cancel != nil { + g.cancel(g.err) + } + return g.err +} + +// Go calls the given function in a new goroutine. +// It blocks until the new goroutine can be added without the number of +// active goroutines in the group exceeding the configured limit. +// +// The first call to return a non-nil error cancels the group's context, if the +// group was created by calling WithContext. The error will be returned by Wait. +func (g *Group) Go(f func() error) { + if g.sem != nil { + g.sem <- token{} + } + + g.wg.Add(1) + go func() { + defer g.done() + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel(g.err) + } + }) + } + }() +} + +// TryGo calls the given function in a new goroutine only if the number of +// active goroutines in the group is currently below the configured limit. +// +// The return value reports whether the goroutine was started. +func (g *Group) TryGo(f func() error) bool { + if g.sem != nil { + select { + case g.sem <- token{}: + // Note: this allows barging iff channels in general allow barging. + default: + return false + } + } + + g.wg.Add(1) + go func() { + defer g.done() + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel(g.err) + } + }) + } + }() + return true +} + +// SetLimit limits the number of active goroutines in this group to at most n. +// A negative value indicates no limit. +// +// Any subsequent call to the Go method will block until it can add an active +// goroutine without exceeding the configured limit. +// +// The limit must not be modified while any goroutines in the group are active. +func (g *Group) SetLimit(n int) { + if n < 0 { + g.sem = nil + return + } + if len(g.sem) != 0 { + panic(fmt.Errorf("errgroup: modify limit while %v goroutines in the group are still active", len(g.sem))) + } + g.sem = make(chan token, n) +} diff --git a/vendor/golang.org/x/sync/errgroup/go120.go b/vendor/golang.org/x/sync/errgroup/go120.go new file mode 100644 index 000000000..f93c740b6 --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/go120.go @@ -0,0 +1,13 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.20 + +package errgroup + +import "context" + +func withCancelCause(parent context.Context) (context.Context, func(error)) { + return context.WithCancelCause(parent) +} diff --git a/vendor/golang.org/x/sync/errgroup/pre_go120.go b/vendor/golang.org/x/sync/errgroup/pre_go120.go new file mode 100644 index 000000000..88ce33434 --- /dev/null +++ b/vendor/golang.org/x/sync/errgroup/pre_go120.go @@ -0,0 +1,14 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.20 + +package errgroup + +import "context" + +func withCancelCause(parent context.Context) (context.Context, func(error)) { + ctx, cancel := context.WithCancel(parent) + return ctx, func(error) { cancel() } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index f0fab3909..464fa385b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -69,19 +69,6 @@ github.com/coreos/go-iptables/iptables # github.com/coreos/go-systemd/v22 v22.5.0 ## explicit; go 1.12 github.com/coreos/go-systemd/v22/activation -# github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c -## explicit -github.com/d2g/dhcp4 -# github.com/d2g/dhcp4client v1.0.0 -## explicit -github.com/d2g/dhcp4client -# github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5 -## explicit -github.com/d2g/dhcp4server -github.com/d2g/dhcp4server/leasepool -github.com/d2g/dhcp4server/leasepool/memorypool -# github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4 -## explicit # github.com/go-logr/logr v1.4.2 ## explicit; go 1.18 github.com/go-logr/logr @@ -105,9 +92,25 @@ github.com/google/go-cmp/cmp/internal/value # github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 ## explicit; go 1.22 github.com/google/pprof/profile +# github.com/insomniacslk/dhcp v0.0.0-20240829085014-a3a4c1f04475 +## explicit; go 1.20 +github.com/insomniacslk/dhcp/dhcpv4 +github.com/insomniacslk/dhcp/dhcpv4/nclient4 +github.com/insomniacslk/dhcp/iana +github.com/insomniacslk/dhcp/interfaces +github.com/insomniacslk/dhcp/rfc1035label +# github.com/josharian/native v1.1.0 +## explicit; go 1.13 +github.com/josharian/native # github.com/mattn/go-shellwords v1.0.12 ## explicit; go 1.13 github.com/mattn/go-shellwords +# github.com/mdlayher/packet v1.1.2 +## explicit; go 1.20 +github.com/mdlayher/packet +# github.com/mdlayher/socket v0.5.1 +## explicit; go 1.20 +github.com/mdlayher/socket # github.com/networkplumbing/go-nft v0.4.0 ## explicit; go 1.16 github.com/networkplumbing/go-nft/nft @@ -154,6 +157,13 @@ github.com/onsi/gomega/types ## explicit; go 1.19 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/pkg/pwalkdir +# github.com/pierrec/lz4/v4 v4.1.21 +## explicit; go 1.14 +github.com/pierrec/lz4/v4 +github.com/pierrec/lz4/v4/internal/lz4block +github.com/pierrec/lz4/v4/internal/lz4errors +github.com/pierrec/lz4/v4/internal/lz4stream +github.com/pierrec/lz4/v4/internal/xxh32 # github.com/pkg/errors v0.9.1 ## explicit github.com/pkg/errors @@ -163,6 +173,10 @@ github.com/safchain/ethtool # github.com/sirupsen/logrus v1.9.3 ## explicit; go 1.13 github.com/sirupsen/logrus +# github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 +## explicit; go 1.21 +github.com/u-root/uio/rand +github.com/u-root/uio/uio # github.com/vishvananda/netlink v1.3.0 ## explicit; go 1.12 github.com/vishvananda/netlink @@ -184,9 +198,9 @@ golang.org/x/net/context golang.org/x/net/html golang.org/x/net/html/atom golang.org/x/net/html/charset -golang.org/x/net/internal/iana -golang.org/x/net/internal/socket -golang.org/x/net/ipv4 +# golang.org/x/sync v0.8.0 +## explicit; go 1.18 +golang.org/x/sync/errgroup # golang.org/x/sys v0.26.0 ## explicit; go 1.18 golang.org/x/sys/unix